1d35bf61b97df6e94e87b12e479e352b6242ca38
[platform/upstream/libsolv.git] / bindings / solv.i
1 /*
2  * WARNING: for perl iterator/array support you need to run
3  *   sed -i -e 's/SvTYPE(tsv) == SVt_PVHV/SvTYPE(tsv) == SVt_PVHV || SvTYPE(tsv) == SVt_PVAV/'
4  * on the generated c code
5  */
6
7 %module solv
8
9 #ifdef SWIGRUBY
10 %markfunc Pool "mark_Pool";
11 #endif
12
13 #ifdef SWIGPYTHON
14 %begin %{
15 #define PY_SSIZE_T_CLEAN
16 %}
17 #endif
18
19 /**
20  ** binaryblob handling
21  **/
22
23 %{
24 typedef struct {
25   const void *data;
26   size_t len;
27 } BinaryBlob;
28 %}
29
30 %typemap(in,noblock=1,fragment="SWIG_AsCharPtrAndSize") (const unsigned char *str, size_t len) (int res, char *buf = 0, size_t size = 0, int alloc = 0) {
31 #if defined(SWIGTCL)
32   {
33     int bal;
34     unsigned char *ba;
35     res = SWIG_TypeError;
36     ba = Tcl_GetByteArrayFromObj($input, &bal);
37     if (ba) {
38       buf = (char *)ba;
39       size = bal;
40       res = SWIG_OK;
41       alloc = SWIG_OLDOBJ;
42     }
43   }
44 #else
45   res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
46   if (buf && size)
47     size--;
48 #endif
49   if (!SWIG_IsOK(res)) {
50 #if defined(SWIGPYTHON)
51     const void *pybuf = 0;
52     Py_ssize_t pysize = 0;
53 %#if PY_VERSION_HEX >= 0x03000000
54     res = PyBytes_AsStringAndSize($input, (char **)&pybuf, &pysize);
55 %#else
56     res = PyObject_AsReadBuffer($input, &pybuf, &pysize);
57 %#endif
58     if (res < 0) {
59       %argument_fail(res, "BinaryBlob", $symname, $argnum);
60     } else {
61       buf = (void *)pybuf;
62       size = pysize;
63     }
64 #else
65     %argument_fail(res, "const char *", $symname, $argnum);
66 #endif
67   }
68   $1 = (unsigned char *)buf;
69   $2 = size;
70 }
71
72 %typemap(freearg,noblock=1,match="in") (const unsigned char *str, size_t len) {
73   if (alloc$argnum == SWIG_NEWOBJ) %delete_array(buf$argnum);
74 }
75
76 %typemap(out,noblock=1,fragment="SWIG_FromCharPtrAndSize") BinaryBlob {
77 #if defined(SWIGPYTHON) && defined(PYTHON3)
78   $result = $1.data ? Py_BuildValue("y#", $1.data, (Py_ssize_t)$1.len) : SWIG_Py_Void();
79 #elif defined(SWIGTCL)
80   Tcl_SetObjResult(interp, $1.data ? Tcl_NewByteArrayObj($1.data, $1.len) : NULL);
81 #else
82   $result = SWIG_FromCharPtrAndSize($1.data, $1.len);
83 #if defined(SWIGPERL)
84   argvi++;
85 #endif
86 #endif
87 }
88
89 /**
90  ** Queue handling
91  **/
92
93 %typemap(arginit) Queue {
94   queue_init(&$1);
95 }
96 %typemap(freearg) Queue {
97   queue_free(&$1);
98 }
99
100 #if defined(SWIGPYTHON)
101
102 %typemap(out) Queue {
103   int i;
104   PyObject *o = PyList_New($1.count);
105   for (i = 0; i < $1.count; i++)
106     PyList_SetItem(o, i, SWIG_From_int($1.elements[i]));
107   queue_free(&$1);
108   $result = o;
109 }
110
111 %define Queue2Array(type, step, con) %{ {
112   int i;
113   int cnt = $1.count / step;
114   Id *idp = $1.elements;
115   PyObject *o = PyList_New(cnt);
116   for (i = 0; i < cnt; i++, idp += step)
117     {
118       Id id = *idp;
119 #define result resultx
120       type result = con;
121       $typemap(out, type)
122       PyList_SetItem(o, i, $result);
123 #undef result
124     }
125   queue_free(&$1);
126   $result = o;
127 }
128 %}
129 %enddef
130
131 %define Array2Queue(asval_meth,typestr) %{ {
132   int i, size;
133   if (!PyList_Check($input))
134     SWIG_exception_fail(SWIG_TypeError, "argument $argnum is not a list");
135   size = PyList_Size($input);
136   for (i = 0; i < size; i++) {
137     PyObject *o = PyList_GetItem($input,i);
138     int v;
139     int e = asval_meth(o, &v);
140     if (!SWIG_IsOK(e))
141       SWIG_exception_fail(SWIG_ArgError(e), "list in argument $argnum must contain only" typestr);
142     queue_push(&$1, v);
143   }
144 }
145 %}
146 %enddef
147
148 %define ObjArray2Queue(type, obj2queue) %{ {
149   int i, size;
150   if (!PyList_Check($input))
151     SWIG_exception_fail(SWIG_TypeError, "argument $argnum is not a list");
152   size = PyList_Size($input);
153   for (i = 0; i < size; i++) {
154     PyObject *o = PyList_GetItem($input,i);
155     type obj;
156     int e = SWIG_ConvertPtr(o, (void **)&obj, $descriptor(type), 0 | 0);
157     if (!SWIG_IsOK(e))
158       SWIG_exception_fail(SWIG_ArgError(e), "list in argument $argnum must contain only "`type`);
159     obj2queue;
160   }
161 }
162 %}
163 %enddef
164
165 #endif  /* SWIGPYTHON */
166
167 #if defined(SWIGPERL)
168 /* AV *o = newAV();
169  * av_push(o, SvREFCNT_inc(SWIG_From_int($1.elements[i])));
170  * $result = newRV_noinc((SV*)o); argvi++;
171  */
172 %typemap(out) Queue {
173   int i;
174   if (argvi + $1.count + 1 >= items) {
175     EXTEND(sp, (argvi + $1.count + 1) - items + 1);
176   }
177   for (i = 0; i < $1.count; i++)
178     ST(argvi++) = SvREFCNT_inc(SWIG_From_int($1.elements[i]));
179   queue_free(&$1);
180   $result = 0;
181 }
182
183 %define Queue2Array(type, step, con) %{ {
184   int i;
185   int cnt = $1.count / step;
186   Id *idp = $1.elements;
187   if (argvi + cnt + 1 >= items) {
188     EXTEND(sp, (argvi + cnt + 1) - items + 1);
189   }
190   for (i = 0; i < cnt; i++, idp += step)
191     {
192       Id id = *idp;
193 #define result resultx
194       type result = con;
195       $typemap(out, type)
196       SvREFCNT_inc(ST(argvi - 1));
197 #undef result
198     }
199   queue_free(&$1);
200   $result = 0;
201 }
202 %}
203 %enddef
204
205 %define Array2Queue(asval_meth,typestr) %{ {
206   AV *av;
207   int i, size;
208   if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV)
209     SWIG_croak("argument $argnum is not an array reference.");
210   av = (AV*)SvRV($input);
211   size = av_len(av);
212   for (i = 0; i <= size; i++) {
213     SV **sv = av_fetch(av, i, 0);
214     int v;
215     int e = asval_meth(*sv, &v);
216     if (!SWIG_IsOK(e))
217       SWIG_croak("array in argument $argnum must contain only " typestr);
218     queue_push(&$1, v);
219   }
220 }
221 %}
222 %enddef
223
224 %define ObjArray2Queue(type, obj2queue) %{ {
225   AV *av;
226   int i, size;
227   if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV)
228     SWIG_croak("argument $argnum is not an array reference.");
229   av = (AV*)SvRV($input);
230   size = av_len(av);
231   for (i = 0; i <= size; i++) {
232     SV **sv = av_fetch(av, i, 0);
233     type obj;
234     int e = SWIG_ConvertPtr(*sv, (void **)&obj, $descriptor(type), 0 | 0);
235     if (!SWIG_IsOK(e))
236       SWIG_exception_fail(SWIG_ArgError(e), "list in argument $argnum must contain only "`type`);
237     obj2queue;
238   }
239 }
240 %}
241 %enddef
242
243 #endif  /* SWIGPERL */
244
245
246 #if defined(SWIGRUBY)
247 %typemap(out) Queue {
248   int i;
249   VALUE o = rb_ary_new2($1.count);
250   for (i = 0; i < $1.count; i++)
251     rb_ary_store(o, i, SWIG_From_int($1.elements[i]));
252   queue_free(&$1);
253   $result = o;
254 }
255
256 %define Queue2Array(type, step, con) %{ {
257   int i;
258   int cnt = $1.count / step;
259   Id *idp = $1.elements;
260   VALUE o = rb_ary_new2(cnt);
261   for (i = 0; i < cnt; i++, idp += step)
262     {
263       Id id = *idp;
264 #define result resultx
265       type result = con;
266       $typemap(out, type)
267       rb_ary_store(o, i, $result);
268 #undef result
269     }
270   queue_free(&$1);
271   $result = o;
272 }
273 %}
274 %enddef
275
276 %define Array2Queue(asval_meth,typestr) %{ {
277   int size, i;
278   VALUE *o, ary;
279   ary = rb_Array($input);
280   size = RARRAY_LEN(ary);
281   i = 0;
282   o = RARRAY_PTR(ary);
283   for (i = 0; i < size; i++, o++) {
284     int v;
285     int e = asval_meth(*o, &v);
286     if (!SWIG_IsOK(e))
287       SWIG_exception_fail(SWIG_TypeError, "list in argument $argnum must contain only " typestr);
288     queue_push(&$1, v);
289   }
290 }
291 %}
292 %enddef
293
294 %define ObjArray2Queue(type, obj2queue) %{ {
295   int size, i;
296   VALUE *o, ary;
297   ary = rb_Array($input);
298   size = RARRAY_LEN(ary);
299   i = 0;
300   o = RARRAY_PTR(ary);
301   for (i = 0; i < size; i++, o++) {
302     type obj;
303     int e = SWIG_ConvertPtr(*o, (void **)&obj, $descriptor(type), 0 | 0);
304     if (!SWIG_IsOK(e))
305       SWIG_exception_fail(SWIG_ArgError(e), "list in argument $argnum must contain only "`type`);
306     obj2queue;
307   }
308 }
309 %}
310 %enddef
311
312 #endif  /* SWIGRUBY */
313
314 #if defined(SWIGTCL)
315 %typemap(out) Queue {
316   Tcl_Obj *objvx[$1.count];
317   int i;
318
319   for (i = 0; i < $1.count; i++) {
320     objvx[i] = SWIG_From_int($1.elements[i]);
321   }
322   Tcl_SetObjResult(interp, Tcl_NewListObj($1.count, objvx));
323   queue_free(&$1);
324 }
325
326 %define Queue2Array(type, step, con) %{
327   { /* scope is needed to make the goto of SWIG_exception_fail work */
328     int i;
329     int cnt = $1.count / step;
330     Id *idp = $1.elements;
331     Tcl_Obj *objvx[cnt];
332
333     for (i = 0; i < cnt; i++, idp += step) {
334       Id id = *idp;
335 #define result resultx
336 #define Tcl_SetObjResult(i, x) resultobj = x
337       type result = con;
338       Tcl_Obj *resultobj;
339       $typemap(out, type)
340       objvx[i] = resultobj;
341 #undef Tcl_SetObjResult
342 #undef result
343     }
344     queue_free(&$1);
345     Tcl_SetObjResult(interp, Tcl_NewListObj(cnt, objvx));
346  }
347 %}
348 %enddef
349
350 %define Array2Queue(asval_meth,typestr) %{ {
351   int size = 0;
352   int i = 0;
353   if (TCL_OK != Tcl_ListObjLength(interp, $input, &size))
354     SWIG_exception_fail(SWIG_TypeError, "argument $argnum is not a list");
355   for (i = 0; i < size; i++) {
356     Tcl_Obj *o = NULL;
357     int e, v;
358
359     if (TCL_OK != Tcl_ListObjIndex(interp, $input, i, &o))
360       SWIG_exception_fail(SWIG_IndexError, "failed to retrieve a list member");
361     e = SWIG_AsVal_int SWIG_TCL_CALL_ARGS_2(o, &v);
362     if (!SWIG_IsOK(e))
363       SWIG_exception_fail(SWIG_ArgError(e), "list in argument $argnum must contain only " typestr);
364     queue_push(&$1, v);
365   }
366 }
367 %}
368 %enddef
369
370 %define ObjArray2Queue(type, obj2queue) %{ {
371   int size = 0;
372   int i = 0;
373   if (TCL_OK != Tcl_ListObjLength(interp, $input, &size))
374     SWIG_exception_fail(SWIG_TypeError, "argument $argnum is not a list");
375   for (i = 0; i < size; i++) {
376     Tcl_Obj *o = NULL;
377     type obj;
378     int e;
379     if (TCL_OK != Tcl_ListObjIndex(interp, $input, i, &o))
380       SWIG_exception_fail(SWIG_IndexError, "failed to retrieve a list member");
381     e = SWIG_ConvertPtr(o, (void **)&obj, $descriptor(type), 0 | 0);
382     if (!SWIG_IsOK(e))
383       SWIG_exception_fail(SWIG_ArgError(e), "list in argument $argnum must contain only "`type`);
384     obj2queue;
385   }
386 }
387 %}
388 %enddef
389
390 #endif  /* SWIGTCL */
391
392 %typemap(in) Queue Array2Queue(SWIG_AsVal_int, "integers")
393 %typemap(in) Queue solvejobs ObjArray2Queue(Job *, queue_push2(&$1, obj->how, obj->what))
394 %typemap(in) Queue solvables ObjArray2Queue(XSolvable *, queue_push(&$1, obj->id))
395
396
397
398 #if defined(SWIGPERL)
399
400 /* work around a swig bug for swig versions < 2.0.5 */
401 #if SWIG_VERSION < 0x020005
402 %{
403 #undef SWIG_CALLXS
404 #ifdef PERL_OBJECT
405 #  define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv,pPerl)
406 #else
407 #  ifndef MULTIPLICITY
408 #    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv)
409 #  else
410 #    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(PERL_GET_THX, cv)
411 #  endif
412 #endif
413 %}
414 #endif
415
416
417 %define perliter(class)
418   %perlcode {
419     sub class##::FETCH {
420       my $i = ${##class##::ITERATORS}{$_[0]};
421       if ($i) {
422         $_[1] == $i->[0] - 1 ? $i->[1] : undef;
423       } else {
424         $_[0]->__getitem__($_[1]);
425       }
426     }
427     sub class##::FETCHSIZE {
428       my $i = ${##class##::ITERATORS}{$_[0]};
429       if ($i) {
430         ($i->[1] = $_[0]->__next__()) ? ++$i->[0]  : 0;
431       } else {
432         $_[0]->__len__();
433       }
434     }
435   }
436 %enddef
437
438 %{
439
440 #define SWIG_PERL_ITERATOR      0x80
441
442 SWIGRUNTIMEINLINE SV *
443 SWIG_Perl_NewArrayObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int flags) {
444   SV *result = sv_newmortal();
445   if (ptr && (flags & (SWIG_SHADOW | SWIG_POINTER_OWN))) {
446     SV *self;
447     SV *obj=newSV(0);
448     AV *array=newAV();
449     HV *stash;
450     sv_setref_pv(obj, (char *) SWIG_Perl_TypeProxyName(t), ptr);
451     stash=SvSTASH(SvRV(obj));
452     if (flags & SWIG_POINTER_OWN) {
453       HV *hv;
454       GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE);
455       if (!isGV(gv))
456         gv_init(gv, stash, "OWNER", 5, FALSE);
457       hv=GvHVn(gv);
458       hv_store_ent(hv, obj, newSViv(1), 0);
459     }
460     if (flags & SWIG_PERL_ITERATOR) {
461       HV *hv;
462       GV *gv=*(GV**)hv_fetch(stash, "ITERATORS", 9, TRUE);
463       AV *av=newAV();
464       if (!isGV(gv))
465         gv_init(gv, stash, "ITERATORS", 9, FALSE);
466       hv=GvHVn(gv);
467       hv_store_ent(hv, obj, newRV_inc((SV *)av), 0);
468     }
469     sv_magic((SV *)array, (SV *)obj, 'P', Nullch, 0);
470     SvREFCNT_dec(obj);
471     self=newRV_noinc((SV *)array);
472     sv_setsv(result, self);
473     SvREFCNT_dec((SV *)self);
474     sv_bless(result, stash);
475   } else {
476     sv_setref_pv(result, (char *) SWIG_Perl_TypeProxyName(t), ptr);
477   }
478   return result;
479 }
480
481 %}
482
483 %typemap(out) Perlarray {
484   ST(argvi) = SWIG_Perl_NewArrayObj(SWIG_PERL_OBJECT_CALL SWIG_as_voidptr(result), $1_descriptor, $owner | $shadow); argvi++;
485 }
486 %typemap(out) Perliterator {
487   ST(argvi) = SWIG_Perl_NewArrayObj(SWIG_PERL_OBJECT_CALL SWIG_as_voidptr(result), $1_descriptor, $owner | $shadow | SWIG_PERL_ITERATOR); argvi++;
488 }
489
490 %typemap(out) Pool_solvable_iterator * = Perlarray;
491 %typemap(out) Pool_solvable_iterator * solvables_iter = Perliterator;
492 %typemap(out) Pool_repo_iterator * = Perlarray;
493 %typemap(out) Pool_repo_iterator * repos_iter = Perliterator;
494 %typemap(out) Repo_solvable_iterator * = Perlarray;
495 %typemap(out) Repo_solvable_iterator * solvables_iter = Perliterator;
496 %typemap(out) Dataiterator * = Perliterator;
497
498 #endif  /* SWIGPERL */
499
500
501 /**
502  ** appdata handling
503  **/
504
505 #if defined(SWIGPYTHON)
506 typedef PyObject *AppObjectPtr;
507 %typemap(in) AppObjectPtr {
508   if ($input)
509     Py_INCREF($input);
510   $1 = $input;
511 }
512 %typemap(out) AppObjectPtr {
513   $result = $1 ? $1 : Py_None;
514   Py_INCREF($result);
515 }
516 #elif defined(SWIGPERL)
517 typedef SV *AppObjectPtr;
518 %typemap(in) AppObjectPtr {
519   if ($input) {
520     $1 = newSV(0);
521     sv_setsv((SV *)$1, $input);
522   } else
523     $1 = (void *)0;
524 }
525 %typemap(out) AppObjectPtr {
526   $result = sv_2mortal($1 ? SvREFCNT_inc($1) : newSV(0));
527   argvi++;
528 }
529 #elif defined(SWIGRUBY)
530 typedef VALUE AppObjectPtr;
531 %typemap(in) AppObjectPtr {
532   $1 = (void *)$input;
533 }
534 %typemap(out) AppObjectPtr {
535   $result = (VALUE)$1;
536 }
537 #elif defined(SWIGTCL)
538 typedef Tcl_Obj *AppObjectPtr;
539 %typemap(in) AppObjectPtr {
540   if ($input)
541     Tcl_IncrRefCount($input);
542   $1 = (void *)$input;
543 }
544 %typemap(out) AppObjectPtr {
545   Tcl_SetObjResult(interp, $1 ? $1 : Tcl_NewObj());
546 }
547 #else
548 #warning AppObjectPtr not defined for this language!
549 #endif
550
551 /**
552  ** FILE handling
553  **/
554
555 #ifdef SWIGPYTHON
556 %include "file.i"
557 #else
558 %fragment("SWIG_AsValFilePtr","header") {}
559 #endif
560
561
562 %fragment("SWIG_AsValSolvFpPtr","header", fragment="SWIG_AsValFilePtr") {
563
564 SWIGINTERN int
565 #ifdef SWIGRUBY
566 SWIG_AsValSolvFpPtr(VALUE obj, FILE **val) {
567 #elif defined(SWIGTCL)
568 SWIG_AsValSolvFpPtr SWIG_TCL_DECL_ARGS_2(void *obj, FILE **val) {
569 #else
570 SWIG_AsValSolvFpPtr(void *obj, FILE **val) {
571 #endif
572   static swig_type_info* desc = 0;
573   void *vptr = 0;
574   int ecode;
575
576   if (!desc) desc = SWIG_TypeQuery("SolvFp *");
577   if ((SWIG_ConvertPtr(obj, &vptr, desc, 0)) == SWIG_OK) {
578     if (val)
579       *val = vptr ? ((SolvFp *)vptr)->fp : 0;
580     return SWIG_OK;
581   }
582 #ifdef SWIGPYTHON
583   ecode = SWIG_AsValFilePtr(obj, val);
584   if (ecode == SWIG_OK)
585     return ecode;
586 #endif
587   return SWIG_TypeError;
588 }
589
590 #if defined(SWIGTCL)
591 #define SWIG_AsValSolvFpPtr(x, y) SWIG_AsValSolvFpPtr SWIG_TCL_CALL_ARGS_2(x, y)
592 #endif
593
594 }
595
596
597 /**
598  ** DepId handling
599  **/
600
601 %fragment("SWIG_AsValDepId","header") {
602
603 SWIGINTERN int
604 #ifdef SWIGRUBY
605 SWIG_AsValDepId(VALUE obj, int *val) {
606 #elif defined(SWIGTCL)
607 SWIG_AsValDepId SWIG_TCL_DECL_ARGS_2(void *obj, int *val) {
608 #else
609 SWIG_AsValDepId(void *obj, int *val) {
610 #endif
611   static swig_type_info* desc = 0;
612   void *vptr = 0;
613   int ecode;
614   if (!desc) desc = SWIG_TypeQuery("Dep *");
615 #ifdef SWIGTCL
616   ecode = SWIG_AsVal_int SWIG_TCL_CALL_ARGS_2(obj, val);
617 #else
618   ecode = SWIG_AsVal_int(obj, val);
619 #endif
620   if (SWIG_IsOK(ecode))
621     return ecode;
622   if ((SWIG_ConvertPtr(obj, &vptr, desc, 0)) == SWIG_OK) {
623     if (val)
624       *val = vptr ? ((Dep *)vptr)->id : 0;
625     return SWIG_OK;
626   }
627   return SWIG_TypeError;
628 }
629
630 #ifdef SWIGTCL
631 #define SWIG_AsValDepId(x, y) SWIG_AsValDepId SWIG_TCL_CALL_ARGS_2(x, y)
632 #endif
633 }
634
635 /**
636  ** Pool disown helper
637  **/
638
639 %typemap(out) disown_helper {
640 #if defined(SWIGRUBY)
641   SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN |  0 );
642 #elif defined(SWIGPYTHON)
643   SWIG_ConvertPtr($self, &argp1,SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN |  0 );
644 #elif defined(SWIGPERL)
645   SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN |  0 );
646 #elif defined(SWIGTCL)
647   SWIG_ConvertPtr(objv[1], &argp1, SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN | 0);
648 #else
649 #warning disown_helper not implemented for this language, this is likely going to leak memory
650 #endif
651
652 #ifdef SWIGTCL
653   Tcl_SetObjResult(interp, SWIG_From_int((int)(0)));
654 #else
655   $result = SWIG_From_int((int)(0));
656 #endif
657 }
658
659
660 /**
661  ** return $self
662  **/
663
664 %define returnself(func)
665 #if defined(SWIGPYTHON)
666 %typemap(out) void func {
667   $result = $self;
668   Py_INCREF($result);
669 }
670 #elif defined(SWIGPERL)
671 %typemap(out) void func {
672   $result = sv_2mortal(SvREFCNT_inc(ST(0)));argvi++;
673 }
674 #elif defined(SWIGRUBY)
675 %typemap(ret) void func {
676   return self;
677 }
678 #elif defined(SWIGTCL)
679 %typemap(out) void func {
680   Tcl_IncrRefCount(objv[1]);
681   Tcl_SetObjResult(interp, objv[1]);
682 }
683 #endif
684 %enddef
685
686
687 /**
688  ** misc stuff
689  **/
690
691 %include "typemaps.i"
692
693 %typemap(in,numinputs=0,noblock=1) XRule **OUTPUT ($*1_ltype temp) {
694   $1 = &temp;
695 }
696 %typemap(argout,noblock=1) XRule **OUTPUT {
697   %append_output(SWIG_NewPointerObj((void*)(*$1), SWIGTYPE_p_XRule, SWIG_POINTER_OWN | %newpointer_flags));
698 }
699
700 %typemaps_asval(%checkcode(POINTER), SWIG_AsValSolvFpPtr, "SWIG_AsValSolvFpPtr", FILE*);
701 %typemaps_asval(%checkcode(INT32), SWIG_AsValDepId, "SWIG_AsValDepId", DepId);
702
703
704 /**
705  ** the C declarations
706  **/
707
708 %{
709 #include <stdbool.h>
710 #include <stdio.h>
711 #include <sys/stat.h>
712 #include <sys/utsname.h>
713 #include <sys/types.h>
714 #include <unistd.h>
715 #include <fcntl.h>
716
717 /* argh, swig undefs bool for perl */
718 #ifndef bool
719 typedef int bool;
720 #endif
721
722 #include "pool.h"
723 #include "poolarch.h"
724 #include "evr.h"
725 #include "solver.h"
726 #include "policy.h"
727 #include "solverdebug.h"
728 #include "repo_solv.h"
729 #include "chksum.h"
730 #include "selection.h"
731
732 #include "repo_write.h"
733 #if defined(ENABLE_RPMDB) || defined(ENABLE_RPMPKG)
734 #include "repo_rpmdb.h"
735 #endif
736 #ifdef ENABLE_PUBKEY
737 #include "repo_pubkey.h"
738 #endif
739 #ifdef ENABLE_DEBIAN
740 #include "repo_deb.h"
741 #endif
742 #ifdef ENABLE_RPMMD
743 #include "repo_rpmmd.h"
744 #include "repo_updateinfoxml.h"
745 #include "repo_deltainfoxml.h"
746 #include "repo_repomdxml.h"
747 #endif
748 #ifdef ENABLE_SUSEREPO
749 #include "repo_products.h"
750 #include "repo_susetags.h"
751 #include "repo_content.h"
752 #endif
753 #ifdef ENABLE_MDKREPO
754 #include "repo_mdk.h"
755 #endif
756 #ifdef ENABLE_ARCHREPO
757 #include "repo_arch.h"
758 #endif
759 #ifdef SUSE
760 #include "repo_autopattern.h"
761 #endif
762 #if defined(ENABLE_COMPLEX_DEPS) && (defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_RPMDB) || defined(ENABLE_RPMPKG))
763 #include "pool_parserpmrichdep.h"
764 #endif
765 #include "solv_xfopen.h"
766 #include "testcase.h"
767
768 /* for old ruby versions */
769 #ifndef RARRAY_PTR
770 #define RARRAY_PTR(ary) (RARRAY(ary)->ptr)
771 #endif
772 #ifndef RARRAY_LEN
773 #define RARRAY_LEN(ary) (RARRAY(ary)->len)
774 #endif
775
776 #define SOLVER_SOLUTION_ERASE                   -100
777 #define SOLVER_SOLUTION_REPLACE                 -101
778 #define SOLVER_SOLUTION_REPLACE_DOWNGRADE       -102
779 #define SOLVER_SOLUTION_REPLACE_ARCHCHANGE      -103
780 #define SOLVER_SOLUTION_REPLACE_VENDORCHANGE    -104
781 #define SOLVER_SOLUTION_REPLACE_NAMECHANGE      -105
782
783 typedef void *AppObjectPtr;
784 typedef Id DepId;
785
786 typedef struct {
787   Pool *pool;
788   Id id;
789 } Dep;
790
791 typedef struct {
792   Pool *pool;
793   Id id;
794 } XSolvable;
795
796 typedef struct {
797   Solver *solv;
798   Id id;
799 } XRule;
800
801 typedef struct {
802   Repo *repo;
803   Id id;
804 } XRepodata;
805
806 typedef struct {
807   Pool *pool;
808   Id id;
809 } Pool_solvable_iterator;
810
811 typedef struct {
812   Pool *pool;
813   Id id;
814 } Pool_repo_iterator;
815
816 typedef struct {
817   Repo *repo;
818   Id id;
819 } Repo_solvable_iterator;
820
821 typedef struct {
822   Pool *pool;
823   int how;
824   Id what;
825 } Job;
826
827 typedef struct {
828   Solver *solv;
829   Id id;
830 } Problem;
831
832 typedef struct {
833   Solver *solv;
834   Id problemid;
835   Id id;
836 } Solution;
837
838 typedef struct {
839   Solver *solv;
840   Id problemid;
841   Id solutionid;
842   Id id;
843
844   Id type;
845   Id p;
846   Id rp;
847 } Solutionelement;
848
849 typedef struct {
850   Solver *solv;
851   Id rid;
852   Id type;
853   Id source;
854   Id target;
855   Id dep_id;
856 } Ruleinfo;
857
858 typedef struct {
859   Solver *solv;
860   Id type;
861   Id rid;
862   Id from_id;
863   Id dep_id;
864   Id chosen_id;
865   Queue choices;
866   int level;
867 } Alternative;
868
869 typedef struct {
870   Transaction *transaction;
871   int mode;
872   Id type;
873   int count;
874   Id fromid;
875   Id toid;
876 } TransactionClass;
877
878 typedef struct {
879   Pool *pool;
880   Queue q;
881   int flags;
882 } Selection;
883
884 typedef struct {
885   FILE *fp;
886 } SolvFp;
887
888 typedef Dataiterator Datamatch;
889
890 typedef int disown_helper;
891
892 struct myappdata {
893   void *appdata;
894   int disowned;
895 };
896
897
898 %}
899
900 /**
901  ** appdata helpers
902  **/
903
904 #ifdef SWIGRUBY
905
906 %{
907 SWIGINTERN void appdata_disown_helper(void *appdata) {
908 }
909 SWIGINTERN void appdata_clr_helper(void **appdatap) {
910   *appdatap = 0;
911 }
912 SWIGINTERN void appdata_set_helper(void **appdatap, void *appdata) {
913   *appdatap = appdata;
914 }
915 SWIGINTERN void *appdata_get_helper(void *appdata) {
916   return appdata;
917 }
918 %}
919
920 #elif defined(SWIGTCL)
921
922 %{
923 SWIGINTERN void appdata_disown_helper(void *appdata) {
924 }
925 SWIGINTERN void appdata_clr_helper(void **appdatap) {
926   if (*appdatap)
927     Tcl_DecrRefCount((Tcl_Obj *)(*appdatap));
928   *appdatap = 0;
929 }
930 SWIGINTERN void appdata_set_helper(void **appdatap, void *appdata) {
931   appdata_clr_helper(appdatap);
932   *appdatap = appdata;
933 }
934 SWIGINTERN void *appdata_get_helper(void *appdata) {
935   return appdata;
936 }
937 %}
938
939 #elif defined(SWIGPYTHON)
940
941 %{
942 SWIGINTERN void appdata_disown_helper(void *appdata) {
943   struct myappdata *myappdata = appdata;
944   if (!myappdata || !myappdata->appdata || myappdata->disowned)
945     return;
946   myappdata->disowned = 1;
947   Py_DECREF((PyObject *)myappdata->appdata);
948 }
949 SWIGINTERN void appdata_clr_helper(void **appdatap) {
950   struct myappdata *myappdata = *(struct myappdata **)appdatap;
951   if (myappdata && myappdata->appdata && !myappdata->disowned) {
952     Py_DECREF((PyObject *)myappdata->appdata);
953   }
954   *appdatap = solv_free(myappdata);
955 }
956 SWIGINTERN void appdata_set_helper(void **appdatap, void *appdata) {
957   appdata_clr_helper(appdatap);
958   if (appdata) {
959     struct myappdata *myappdata = *appdatap = solv_calloc(sizeof(struct myappdata), 1);
960     myappdata->appdata = appdata;
961   }
962 }
963 SWIGINTERN void *appdata_get_helper(void *appdata) {
964   return appdata ? ((struct myappdata *)appdata)->appdata : 0;
965 }
966
967 %}
968
969 #elif defined(SWIGPERL)
970
971 %{
972 SWIGINTERN void appdata_disown_helper(void *appdata) {
973   struct myappdata *myappdata = appdata;
974   SV *rsv;
975   if (!myappdata || !myappdata->appdata || myappdata->disowned)
976     return;
977   rsv = myappdata->appdata;
978   if (!SvROK(rsv))
979     return;
980   myappdata->appdata = SvRV(rsv);
981   myappdata->disowned = 1;
982   SvREFCNT_dec(rsv);
983 }
984 SWIGINTERN void appdata_clr_helper(void **appdatap) {
985   struct myappdata *myappdata = *(struct myappdata **)appdatap;
986   if (myappdata && myappdata->appdata && !myappdata->disowned) {
987     SvREFCNT_dec((SV *)myappdata->appdata);
988   }
989   *appdatap = solv_free(myappdata);
990 }
991 SWIGINTERN void appdata_set_helper(void **appdatap, void *appdata) {
992   appdata_clr_helper(appdatap);
993   if (appdata) {
994     struct myappdata *myappdata = *appdatap = solv_calloc(sizeof(struct myappdata), 1);
995     myappdata->appdata = appdata;
996   }
997 }
998 SWIGINTERN void *appdata_get_helper(void *appdata) {
999   struct myappdata *myappdata = appdata;
1000   if (!myappdata || !myappdata->appdata)
1001     return 0;
1002   return myappdata->disowned ? newRV_noinc((SV *)myappdata->appdata) : myappdata->appdata;
1003 }
1004
1005 %}
1006
1007 #else
1008 #warning appdata helpers not implemented for this language
1009 #endif
1010
1011
1012 /**
1013  ** the SWIG declarations defining the API
1014  **/
1015
1016 #ifdef SWIGRUBY
1017 %mixin Dataiterator "Enumerable";
1018 %mixin Pool_solvable_iterator "Enumerable";
1019 %mixin Pool_repo_iterator "Enumerable";
1020 %mixin Repo_solvable_iterator "Enumerable";
1021 #endif
1022
1023 typedef int Id;
1024
1025 %include "knownid.h"
1026
1027 /* from repodata.h */
1028 %constant Id SOLVID_META;
1029 %constant Id SOLVID_POS;
1030
1031 %constant int REL_EQ;
1032 %constant int REL_GT;
1033 %constant int REL_LT;
1034 %constant int REL_AND;
1035 %constant int REL_OR;
1036 %constant int REL_WITH;
1037 %constant int REL_NAMESPACE;
1038 %constant int REL_ARCH;
1039 %constant int REL_FILECONFLICT;
1040 %constant int REL_COND;
1041 %constant int REL_COMPAT;
1042 %constant int REL_KIND;
1043 %constant int REL_MULTIARCH;
1044 %constant int REL_ELSE;
1045 %constant int REL_ERROR;
1046 %constant int REL_WITHOUT;
1047 %constant int REL_UNLESS;
1048 %constant int REL_CONDA;
1049
1050 typedef struct {
1051   Pool* const pool;
1052   int const flags;
1053 } Selection;
1054
1055 typedef struct {
1056   Pool* const pool;
1057   Id const id;
1058 } Dep;
1059
1060 /* put before pool/repo so we can access the constructor */
1061 %nodefaultdtor Dataiterator;
1062 typedef struct {} Dataiterator;
1063
1064 typedef struct {
1065   Pool* const pool;
1066   Id const id;
1067 } XSolvable;
1068
1069 typedef struct {
1070   Solver* const solv;
1071   Id const type;
1072   Id const dep_id;
1073 } Ruleinfo;
1074
1075 typedef struct {
1076   Solver* const solv;
1077   Id const id;
1078 } XRule;
1079
1080 typedef struct {
1081   Repo* const repo;
1082   Id const id;
1083 } XRepodata;
1084
1085 typedef struct {} Pool_solvable_iterator;
1086 typedef struct {} Pool_repo_iterator;
1087 typedef struct {} Repo_solvable_iterator;
1088
1089 %nodefaultctor Datamatch;
1090 %nodefaultdtor Datamatch;
1091 typedef struct {
1092   Pool * const pool;
1093   Repo * const repo;
1094   Id const solvid;
1095 } Datamatch;
1096
1097 %nodefaultctor Datapos;
1098 typedef struct {
1099   Repo * const repo;
1100 } Datapos;
1101
1102 typedef struct {
1103   Pool * const pool;
1104   int how;
1105   Id what;
1106 } Job;
1107
1108 %nodefaultctor Pool;
1109 %nodefaultdtor Pool;
1110 typedef struct {
1111 } Pool;
1112
1113 %nodefaultctor Repo;
1114 %nodefaultdtor Repo;
1115 typedef struct {
1116   Pool * const pool;
1117   const char * const name;
1118   int priority;
1119   int subpriority;
1120   int const nsolvables;
1121 } Repo;
1122
1123 %nodefaultctor Solver;
1124 %nodefaultdtor Solver;
1125 typedef struct {
1126   Pool * const pool;
1127 } Solver;
1128
1129 typedef struct {
1130 } Chksum;
1131
1132 #ifdef ENABLE_PUBKEY
1133 typedef struct {
1134   Id const htype;
1135   unsigned int const created;
1136   unsigned int const expires;
1137   const char * const keyid;
1138 } Solvsig;
1139 #endif
1140
1141 %rename(xfopen) solvfp_xfopen;
1142 %rename(xfopen_fd) solvfp_xfopen_fd;
1143
1144 %nodefaultctor SolvFp;
1145 typedef struct {
1146 } SolvFp;
1147
1148 %newobject solvfp_xfopen;
1149 %newobject solvfp_xfopen_fd;
1150
1151 SolvFp *solvfp_xfopen(const char *fn, const char *mode = 0);
1152 SolvFp *solvfp_xfopen_fd(const char *fn, int fd, const char *mode = 0);
1153
1154 %{
1155   SWIGINTERN SolvFp *solvfp_xfopen_fd(const char *fn, int fd, const char *mode) {
1156     SolvFp *sfp;
1157     FILE *fp;
1158     fd = dup(fd);
1159     if (fd == -1)
1160       return 0;
1161     solv_setcloexec(fd, 1);
1162     fp = solv_xfopen_fd(fn, fd, mode);
1163     if (!fp) {
1164       close(fd);
1165       return 0;
1166     }
1167     sfp = solv_calloc(1, sizeof(SolvFp));
1168     sfp->fp = fp;
1169     return sfp;
1170   }
1171   SWIGINTERN SolvFp *solvfp_xfopen(const char *fn, const char *mode) {
1172     SolvFp *sfp;
1173     FILE *fp;
1174     fp = solv_xfopen(fn, mode);
1175     if (!fp)
1176       return 0;
1177     if (fileno(fp) != -1)
1178       solv_setcloexec(fileno(fp), 1);
1179     sfp = solv_calloc(1, sizeof(SolvFp));
1180     sfp->fp = fp;
1181     return sfp;
1182   }
1183 %}
1184
1185 typedef struct {
1186   Solver * const solv;
1187   Id const id;
1188 } Problem;
1189
1190 typedef struct {
1191   Solver * const solv;
1192   Id const problemid;
1193   Id const id;
1194 } Solution;
1195
1196 typedef struct {
1197   Solver *const solv;
1198   Id const problemid;
1199   Id const solutionid;
1200   Id const id;
1201   Id const type;
1202 } Solutionelement;
1203
1204 %nodefaultctor Alternative;
1205 typedef struct {
1206   Solver *const solv;
1207   Id const type;
1208   Id const rid;
1209   Id const from_id;
1210   Id const dep_id;
1211   Id const chosen_id;
1212   int level;
1213 } Alternative;
1214
1215 %nodefaultctor Transaction;
1216 %nodefaultdtor Transaction;
1217 typedef struct {
1218   Pool * const pool;
1219 } Transaction;
1220
1221 typedef struct {
1222   Transaction * const transaction;
1223   Id const type;
1224   Id const fromid;
1225   Id const toid;
1226   int const count;
1227 } TransactionClass;
1228
1229 %extend SolvFp {
1230   ~SolvFp() {
1231     if ($self->fp)
1232       fclose($self->fp);
1233     free($self);
1234   }
1235   int fileno() {
1236     return $self->fp ? fileno($self->fp) : -1;
1237   }
1238   int dup() {
1239     return $self->fp ? dup(fileno($self->fp)) : -1;
1240   }
1241   bool write(const unsigned char *str, size_t len) {
1242     return fwrite(str, len, 1, $self->fp) == 1;
1243   }
1244   bool flush() {
1245     if (!$self->fp)
1246       return 1;
1247     return fflush($self->fp) == 0;
1248   }
1249   bool close() {
1250     bool ret;
1251     if (!$self->fp)
1252       return 1;
1253     ret = fclose($self->fp) == 0;
1254     $self->fp = 0;
1255     return ret;
1256   }
1257   void cloexec(bool state) {
1258     if (!$self->fp || fileno($self->fp) == -1)
1259       return;
1260     solv_setcloexec(fileno($self->fp), state);
1261   }
1262 }
1263
1264 %extend Job {
1265   static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
1266   static const Id SOLVER_SOLVABLE_NAME = SOLVER_SOLVABLE_NAME;
1267   static const Id SOLVER_SOLVABLE_PROVIDES = SOLVER_SOLVABLE_PROVIDES;
1268   static const Id SOLVER_SOLVABLE_ONE_OF = SOLVER_SOLVABLE_ONE_OF;
1269   static const Id SOLVER_SOLVABLE_REPO = SOLVER_SOLVABLE_REPO;
1270   static const Id SOLVER_SOLVABLE_ALL = SOLVER_SOLVABLE_ALL;
1271   static const Id SOLVER_SELECTMASK = SOLVER_SELECTMASK;
1272   static const Id SOLVER_NOOP = SOLVER_NOOP;
1273   static const Id SOLVER_INSTALL = SOLVER_INSTALL;
1274   static const Id SOLVER_ERASE = SOLVER_ERASE;
1275   static const Id SOLVER_UPDATE = SOLVER_UPDATE;
1276   static const Id SOLVER_WEAKENDEPS = SOLVER_WEAKENDEPS;
1277   static const Id SOLVER_MULTIVERSION = SOLVER_MULTIVERSION;
1278   static const Id SOLVER_LOCK = SOLVER_LOCK;
1279   static const Id SOLVER_DISTUPGRADE = SOLVER_DISTUPGRADE;
1280   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
1281   static const Id SOLVER_DROP_ORPHANED = SOLVER_DROP_ORPHANED;
1282   static const Id SOLVER_USERINSTALLED = SOLVER_USERINSTALLED;
1283   static const Id SOLVER_ALLOWUNINSTALL = SOLVER_ALLOWUNINSTALL;
1284   static const Id SOLVER_FAVOR = SOLVER_FAVOR;
1285   static const Id SOLVER_DISFAVOR = SOLVER_DISFAVOR;
1286   static const Id SOLVER_EXCLUDEFROMWEAK = SOLVER_EXCLUDEFROMWEAK;
1287   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
1288   static const Id SOLVER_WEAK = SOLVER_WEAK;
1289   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
1290   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
1291   static const Id SOLVER_FORCEBEST = SOLVER_FORCEBEST;
1292   static const Id SOLVER_TARGETED = SOLVER_TARGETED;
1293   static const Id SOLVER_NOTBYUSER = SOLVER_NOTBYUSER;
1294   static const Id SOLVER_SETEV = SOLVER_SETEV;
1295   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
1296   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
1297   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
1298   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
1299   static const Id SOLVER_SETNAME = SOLVER_SETNAME;
1300   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
1301   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
1302
1303   Job(Pool *pool, int how, Id what) {
1304     Job *job = solv_calloc(1, sizeof(*job));
1305     job->pool = pool;
1306     job->how = how;
1307     job->what = what;
1308     return job;
1309   }
1310
1311   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
1312   %newobject solvables;
1313   Queue solvables() {
1314     Queue q;
1315     queue_init(&q);
1316     pool_job2solvables($self->pool, &q, $self->how, $self->what);
1317     return q;
1318   }
1319 #ifdef SWIGRUBY
1320   %rename("isemptyupdate?") isemptyupdate;
1321 #endif
1322   bool isemptyupdate() {
1323     return pool_isemptyupdatejob($self->pool, $self->how, $self->what);
1324   }
1325
1326 #if defined(SWIGTCL)
1327   %rename("==") __eq__;
1328 #endif
1329   bool __eq__(Job *j) {
1330     return $self->pool == j->pool && $self->how == j->how && $self->what == j->what;
1331   }
1332 #if defined(SWIGTCL)
1333   %rename("!=") __ne__;
1334 #endif
1335   bool __ne__(Job *j) {
1336     return !Job___eq__($self, j);
1337   }
1338 #if defined(SWIGPERL) || defined(SWIGTCL)
1339   %rename("str") __str__;
1340 #endif
1341   const char *__str__() {
1342     return pool_job2str($self->pool, $self->how, $self->what, 0);
1343   }
1344 #if defined(SWIGPERL) || defined(SWIGTCL)
1345   %rename("repr") __repr__;
1346 #endif
1347   const char *__repr__() {
1348     const char *str = pool_job2str($self->pool, $self->how, $self->what, ~0);
1349     return pool_tmpjoin($self->pool, "<Job ", str, ">");
1350   }
1351 }
1352
1353 %extend Selection {
1354   static const Id SELECTION_NAME = SELECTION_NAME;
1355   static const Id SELECTION_PROVIDES = SELECTION_PROVIDES;
1356   static const Id SELECTION_FILELIST = SELECTION_FILELIST;
1357   static const Id SELECTION_CANON = SELECTION_CANON;
1358   static const Id SELECTION_DOTARCH = SELECTION_DOTARCH;
1359   static const Id SELECTION_REL = SELECTION_REL;
1360   static const Id SELECTION_INSTALLED_ONLY = SELECTION_INSTALLED_ONLY;
1361   static const Id SELECTION_GLOB = SELECTION_GLOB;
1362   static const Id SELECTION_FLAT = SELECTION_FLAT;
1363   static const Id SELECTION_NOCASE = SELECTION_NOCASE;
1364   static const Id SELECTION_SKIP_KIND = SELECTION_SKIP_KIND;
1365   static const Id SELECTION_MATCH_DEPSTR = SELECTION_MATCH_DEPSTR;
1366   static const Id SELECTION_SOURCE_ONLY = SELECTION_SOURCE_ONLY;
1367   static const Id SELECTION_WITH_SOURCE = SELECTION_WITH_SOURCE;
1368   static const Id SELECTION_WITH_DISABLED = SELECTION_WITH_DISABLED;
1369   static const Id SELECTION_WITH_BADARCH = SELECTION_WITH_BADARCH;
1370   static const Id SELECTION_WITH_ALL = SELECTION_WITH_ALL;
1371   static const Id SELECTION_ADD = SELECTION_ADD;
1372   static const Id SELECTION_SUBTRACT = SELECTION_SUBTRACT;
1373   static const Id SELECTION_FILTER = SELECTION_FILTER;
1374   static const Id SELECTION_FILTER_KEEP_IFEMPTY = SELECTION_FILTER_KEEP_IFEMPTY;
1375   static const Id SELECTION_FILTER_SWAPPED = SELECTION_FILTER_SWAPPED;
1376
1377   Selection(Pool *pool) {
1378     Selection *s;
1379     s = solv_calloc(1, sizeof(*s));
1380     s->pool = pool;
1381     return s;
1382   }
1383
1384   ~Selection() {
1385     queue_free(&$self->q);
1386     solv_free($self);
1387   }
1388 #ifdef SWIGRUBY
1389   %rename("isempty?") isempty;
1390 #endif
1391   bool isempty() {
1392     return $self->q.count == 0;
1393   }
1394   %newobject clone;
1395   Selection *clone(int flags = 0) {
1396     Selection *s = new_Selection($self->pool);
1397     queue_init_clone(&s->q, &$self->q);
1398     s->flags = $self->flags;
1399     return s;
1400   }
1401 returnself(filter)
1402   void filter(Selection *lsel) {
1403     if ($self->pool != lsel->pool)
1404       queue_empty(&$self->q);
1405     else
1406       selection_filter($self->pool, &$self->q, &lsel->q);
1407   }
1408 returnself(add)
1409   void add(Selection *lsel) {
1410     if ($self->pool == lsel->pool)
1411       {
1412         selection_add($self->pool, &$self->q, &lsel->q);
1413         $self->flags |= lsel->flags;
1414       }
1415   }
1416 returnself(add_raw)
1417   void add_raw(Id how, Id what) {
1418     queue_push2(&$self->q, how, what);
1419   }
1420 returnself(subtract)
1421   void subtract(Selection *lsel) {
1422     if ($self->pool == lsel->pool)
1423       selection_subtract($self->pool, &$self->q, &lsel->q);
1424   }
1425
1426 returnself(select)
1427   void select(const char *name, int flags) {
1428     if ((flags & SELECTION_MODEBITS) == 0)
1429       flags |= SELECTION_FILTER | SELECTION_WITH_ALL;
1430     $self->flags = selection_make($self->pool, &$self->q, name, flags);
1431   }
1432 returnself(matchdeps)
1433   void matchdeps(const char *name, int flags, Id keyname, Id marker = -1) {
1434     if ((flags & SELECTION_MODEBITS) == 0)
1435       flags |= SELECTION_FILTER | SELECTION_WITH_ALL;
1436     $self->flags = selection_make_matchdeps($self->pool, &$self->q, name, flags, keyname, marker);
1437   }
1438 returnself(matchdepid)
1439   void matchdepid(DepId dep, int flags, Id keyname, Id marker = -1) {
1440     if ((flags & SELECTION_MODEBITS) == 0)
1441       flags |= SELECTION_FILTER | SELECTION_WITH_ALL;
1442     $self->flags = selection_make_matchdepid($self->pool, &$self->q, dep, flags, keyname, marker);
1443   }
1444 returnself(matchsolvable)
1445   void matchsolvable(XSolvable *solvable, int flags, Id keyname, Id marker = -1) {
1446     if ((flags & SELECTION_MODEBITS) == 0)
1447       flags |= SELECTION_FILTER | SELECTION_WITH_ALL;
1448     $self->flags = selection_make_matchsolvable($self->pool, &$self->q, solvable->id, flags, keyname, marker);
1449   }
1450
1451   %typemap(out) Queue jobs Queue2Array(Job *, 2, new_Job(arg1->pool, id, idp[1]));
1452   %newobject jobs;
1453   Queue jobs(int flags) {
1454     Queue q;
1455     int i;
1456     queue_init_clone(&q, &$self->q);
1457     for (i = 0; i < q.count; i += 2)
1458       q.elements[i] |= flags;
1459     return q;
1460   }
1461
1462   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
1463   %newobject solvables;
1464   Queue solvables() {
1465     Queue q;
1466     queue_init(&q);
1467     selection_solvables($self->pool, &$self->q, &q);
1468     return q;
1469   }
1470
1471 #if defined(SWIGPERL) || defined(SWIGTCL)
1472   %rename("str") __str__;
1473 #endif
1474   const char *__str__() {
1475     return pool_selection2str($self->pool, &$self->q, 0);
1476   }
1477 #if defined(SWIGPERL) || defined(SWIGTCL)
1478   %rename("repr") __repr__;
1479 #endif
1480   const char *__repr__() {
1481     const char *str = pool_selection2str($self->pool, &$self->q, ~0);
1482     return pool_tmpjoin($self->pool, "<Selection ", str, ">");
1483   }
1484 }
1485
1486 %extend Chksum {
1487   Chksum(Id type) {
1488     return solv_chksum_create(type);
1489   }
1490   Chksum(Id type, const char *hex) {
1491     unsigned char buf[64];
1492     int l = solv_chksum_len(type);
1493     if (!l)
1494       return 0;
1495     if (solv_hex2bin(&hex, buf, sizeof(buf)) != l || hex[0])
1496       return 0;
1497     return solv_chksum_create_from_bin(type, buf);
1498   }
1499   %newobject from_bin;
1500   static Chksum *from_bin(Id type, const unsigned char *str, size_t len) {
1501     return len == solv_chksum_len(type) ? solv_chksum_create_from_bin(type, str) : 0;
1502   }
1503 #if defined(SWIGPERL)
1504   %perlcode {
1505     undef *solv::Chksum::from_bin;
1506     *solv::Chksum::from_bin = sub {
1507       my $pkg = shift;
1508       my $self = solvc::Chksum_from_bin(@_);
1509       bless $self, $pkg if defined $self;
1510     };
1511   }
1512 #endif
1513   ~Chksum() {
1514     solv_chksum_free($self, 0);
1515   }
1516   Id const type;
1517   %{
1518   SWIGINTERN Id Chksum_type_get(Chksum *chk) {
1519     return solv_chksum_get_type(chk);
1520   }
1521   %}
1522   void add(const unsigned char *str, size_t len) {
1523     solv_chksum_add($self, str, (int)len);
1524   }
1525   void add_fp(FILE *fp) {
1526     char buf[4096];
1527     int l;
1528     while ((l = fread(buf, 1, sizeof(buf), fp)) > 0)
1529       solv_chksum_add($self, buf, l);
1530     rewind(fp);         /* convenience */
1531   }
1532   void add_fd(int fd) {
1533     char buf[4096];
1534     int l;
1535     while ((l = read(fd, buf, sizeof(buf))) > 0)
1536       solv_chksum_add($self, buf, l);
1537     lseek(fd, 0, 0);    /* convenience */
1538   }
1539   void add_stat(const char *filename) {
1540     struct stat stb;
1541     if (stat(filename, &stb))
1542       memset(&stb, 0, sizeof(stb));
1543     solv_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
1544     solv_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
1545     solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
1546     solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
1547   }
1548   void add_fstat(int fd) {
1549     struct stat stb;
1550     if (fstat(fd, &stb))
1551       memset(&stb, 0, sizeof(stb));
1552     solv_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
1553     solv_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
1554     solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
1555     solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
1556   }
1557   BinaryBlob raw() {
1558     BinaryBlob bl;
1559     int l;
1560     const unsigned char *b;
1561     b = solv_chksum_get($self, &l);
1562     bl.data = b;
1563     bl.len = l;
1564     return bl;
1565   }
1566   %newobject hex;
1567   char *hex() {
1568     int l;
1569     const unsigned char *b;
1570     char *ret;
1571
1572     b = solv_chksum_get($self, &l);
1573     ret = solv_malloc(2 * l + 1);
1574     solv_bin2hex(b, l, ret);
1575     return ret;
1576   }
1577   const char *typestr() {
1578     return solv_chksum_type2str(solv_chksum_get_type($self));
1579   }
1580
1581 #if defined(SWIGTCL)
1582   %rename("==") __eq__;
1583 #endif
1584   bool __eq__(Chksum *chk) {
1585     return solv_chksum_cmp($self, chk);
1586   }
1587 #if defined(SWIGTCL)
1588   %rename("!=") __ne__;
1589 #endif
1590   bool __ne__(Chksum *chk) {
1591     return !solv_chksum_cmp($self, chk);
1592   }
1593 #if defined(SWIGRUBY)
1594   %rename("to_s") __str__;
1595 #endif
1596 #if defined(SWIGPERL) || defined(SWIGTCL)
1597   %rename("str") __str__;
1598 #endif
1599   %newobject __str__;
1600   const char *__str__() {
1601     const char *str;
1602     const char *h = 0;
1603     if (solv_chksum_isfinished($self))
1604       h = Chksum_hex($self);
1605     str = solv_dupjoin(solv_chksum_type2str(solv_chksum_get_type($self)), ":", h ? h : "unfinished");
1606     solv_free((void *)h);
1607     return str;
1608   }
1609 #if defined(SWIGPERL) || defined(SWIGTCL)
1610   %rename("repr") __repr__;
1611 #endif
1612   %newobject __repr__;
1613   const char *__repr__() {
1614     const char *h = Chksum___str__($self);
1615     const char *str = solv_dupjoin("<Chksum ", h, ">");
1616     solv_free((void *)h);
1617     return str;
1618   }
1619 }
1620
1621 %extend Pool {
1622   static const int POOL_FLAG_PROMOTEEPOCH = POOL_FLAG_PROMOTEEPOCH;
1623   static const int POOL_FLAG_FORBIDSELFCONFLICTS = POOL_FLAG_FORBIDSELFCONFLICTS;
1624   static const int POOL_FLAG_OBSOLETEUSESPROVIDES = POOL_FLAG_OBSOLETEUSESPROVIDES;
1625   static const int POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES = POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES;
1626   static const int POOL_FLAG_OBSOLETEUSESCOLORS = POOL_FLAG_OBSOLETEUSESCOLORS;
1627   static const int POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS = POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS;
1628   static const int POOL_FLAG_NOINSTALLEDOBSOLETES = POOL_FLAG_NOINSTALLEDOBSOLETES;
1629   static const int POOL_FLAG_HAVEDISTEPOCH = POOL_FLAG_HAVEDISTEPOCH;
1630   static const int POOL_FLAG_NOOBSOLETESMULTIVERSION = POOL_FLAG_NOOBSOLETESMULTIVERSION;
1631   static const int DISTTYPE_RPM = DISTTYPE_RPM;
1632   static const int DISTTYPE_DEB = DISTTYPE_DEB;
1633   static const int DISTTYPE_ARCH = DISTTYPE_ARCH;
1634   static const int DISTTYPE_HAIKU = DISTTYPE_HAIKU;
1635
1636   Pool() {
1637     Pool *pool = pool_create();
1638     return pool;
1639   }
1640   int setdisttype(int disttype) {
1641     return pool_setdisttype($self, disttype);
1642   }
1643   void set_debuglevel(int level) {
1644     pool_setdebuglevel($self, level);
1645   }
1646   int set_flag(int flag, int value) {
1647     return pool_set_flag($self, flag, value);
1648   }
1649   int get_flag(int flag) {
1650     return pool_get_flag($self, flag);
1651   }
1652   void set_rootdir(const char *rootdir) {
1653     pool_set_rootdir($self, rootdir);
1654   }
1655   const char *get_rootdir(int flag) {
1656     return pool_get_rootdir($self);
1657   }
1658 #if defined(SWIGPYTHON)
1659   %{
1660   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
1661     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
1662     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
1663     PyObject *result = PyEval_CallObject((PyObject *)d, args);
1664     int ecode = 0;
1665     int vresult = 0;
1666     Py_DECREF(args);
1667     if (!result)
1668       return 0; /* exception */
1669     ecode = SWIG_AsVal_int(result, &vresult);
1670     Py_DECREF(result);
1671     return SWIG_IsOK(ecode) ? vresult : 0;
1672   }
1673   %}
1674   void clr_loadcallback() {
1675     if ($self->loadcallback == loadcallback) {
1676       PyObject *obj = $self->loadcallbackdata;
1677       Py_DECREF(obj);
1678       pool_setloadcallback($self, 0, 0);
1679     }
1680   }
1681   void set_loadcallback(PyObject *callable) {
1682     Pool_clr_loadcallback($self);
1683     if (callable) {
1684       Py_INCREF(callable);
1685       pool_setloadcallback($self, loadcallback, callable);
1686     }
1687   }
1688 #elif defined(SWIGPERL)
1689 %{
1690   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
1691     int count;
1692     int ret = 0;
1693     dSP;
1694     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
1695
1696     ENTER;
1697     SAVETMPS;
1698     PUSHMARK(SP);
1699     XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_OWNER | SWIG_SHADOW));
1700     PUTBACK;
1701     count = perl_call_sv((SV *)d, G_EVAL|G_SCALAR);
1702     SPAGAIN;
1703     if (count)
1704       ret = POPi;
1705     PUTBACK;
1706     FREETMPS;
1707     LEAVE;
1708     return ret;
1709   }
1710 %}
1711   void clr_loadcallback() {
1712     if ($self->loadcallback == loadcallback) {
1713       SvREFCNT_dec($self->loadcallbackdata);
1714       pool_setloadcallback($self, 0, 0);
1715     }
1716   }
1717   void set_loadcallback(SV *callable) {
1718     Pool_clr_loadcallback($self);
1719     if (callable) {
1720       SvREFCNT_inc(callable);
1721       pool_setloadcallback($self, loadcallback, callable);
1722     }
1723   }
1724 #elif defined(SWIGRUBY)
1725 %{
1726   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
1727     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
1728     VALUE callable = (VALUE)d;
1729     VALUE rd = SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0);
1730     VALUE res = rb_funcall(callable, rb_intern("call"), 1, rd);
1731     return res == Qtrue;
1732   }
1733   SWIGINTERN void mark_Pool(void *ptr) {
1734     Pool *pool = ptr;
1735     if (pool->loadcallback == loadcallback && pool->loadcallbackdata) {
1736       VALUE callable = (VALUE)pool->loadcallbackdata;
1737       rb_gc_mark(callable);
1738     }
1739   }
1740 %}
1741   void clr_loadcallback() {
1742     pool_setloadcallback($self, 0, 0);
1743   }
1744   %typemap(in, numinputs=0) VALUE callable {
1745     $1 = rb_block_given_p() ? rb_block_proc() : 0;
1746   }
1747   void set_loadcallback(VALUE callable) {
1748     pool_setloadcallback($self, callable ? loadcallback : 0, (void *)callable);
1749   }
1750 #elif defined(SWIGTCL)
1751   %{
1752   typedef struct {
1753     Tcl_Interp *interp;
1754     Tcl_Obj *obj;
1755   } tcl_callback_t;
1756   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
1757     tcl_callback_t *callback_var = (tcl_callback_t *)d;
1758     Tcl_Interp *interp = callback_var->interp;
1759     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
1760     int result, ecode = 0, vresult = 0;
1761     Tcl_Obj *objvx[2];
1762     objvx[0] = callback_var->obj;
1763     objvx[1] = SWIG_NewInstanceObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, 0);
1764     Tcl_IncrRefCount(objvx[1]);
1765     result = Tcl_EvalObjv(interp, sizeof(objvx)/sizeof(*objvx), objvx, TCL_EVAL_GLOBAL);
1766     Tcl_DecrRefCount(objvx[1]);
1767     if (result != TCL_OK)
1768       return 0; /* exception */
1769     ecode = SWIG_AsVal_int(interp, Tcl_GetObjResult(interp), &vresult);
1770     return SWIG_IsOK(ecode) ? vresult : 0;
1771   }
1772   %}
1773   void clr_loadcallback() {
1774     if ($self->loadcallback == loadcallback) {
1775       tcl_callback_t *callback_var = $self->loadcallbackdata;
1776       Tcl_DecrRefCount(callback_var->obj);
1777       solv_free(callback_var);
1778       pool_setloadcallback($self, 0, 0);
1779     }
1780   }
1781   void set_loadcallback(Tcl_Obj *callable, Tcl_Interp *interp) {
1782     Pool_clr_loadcallback($self);
1783     if (callable) {
1784       tcl_callback_t *callback_var = solv_malloc(sizeof(tcl_callback_t));
1785       Tcl_IncrRefCount(callable);
1786       callback_var->interp = interp;
1787       callback_var->obj = callable;
1788       pool_setloadcallback($self, loadcallback, callback_var);
1789     }
1790   }
1791 #else
1792 #warning loadcallback not implemented for this language
1793 #endif
1794
1795   ~Pool() {
1796     Pool *pool = $self;
1797     Id repoid;
1798     Repo *repo;
1799     FOR_REPOS(repoid, repo)
1800       appdata_clr_helper(&repo->appdata);
1801     Pool_clr_loadcallback(pool);
1802     appdata_clr_helper(&pool->appdata);
1803     pool_free(pool);
1804   }
1805   disown_helper free() {
1806     Pool *pool = $self;
1807     Id repoid;
1808     Repo *repo;
1809     FOR_REPOS(repoid, repo)
1810       appdata_clr_helper(&repo->appdata);
1811     Pool_clr_loadcallback(pool);
1812     appdata_clr_helper(&pool->appdata);
1813     pool_free(pool);
1814     return 0;
1815   }
1816   disown_helper disown() {
1817     return 0;
1818   }
1819   AppObjectPtr appdata;
1820   %{
1821   SWIGINTERN void Pool_appdata_set(Pool *pool, AppObjectPtr appdata) {
1822     appdata_set_helper(&pool->appdata, appdata);
1823   }
1824   SWIGINTERN AppObjectPtr Pool_appdata_get(Pool *pool) {
1825     return appdata_get_helper(pool->appdata);
1826   }
1827   %}
1828   void appdata_disown() {
1829     appdata_disown_helper($self->appdata);
1830   }
1831
1832   Id str2id(const char *str, bool create=1) {
1833     return pool_str2id($self, str, create);
1834   }
1835   %newobject Dep;
1836   Dep *Dep(const char *str, bool create=1) {
1837     Id id = pool_str2id($self, str, create);
1838     return new_Dep($self, id);
1839   }
1840 #if defined(ENABLE_COMPLEX_DEPS) && (defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_RPMDB) || defined(ENABLE_RPMPKG))
1841   %newobject Dep;
1842   Dep *parserpmrichdep(const char *str) {
1843     Id id = pool_parserpmrichdep($self, str);
1844     return new_Dep($self, id);
1845   }
1846 #endif
1847   const char *id2str(Id id) {
1848     return pool_id2str($self, id);
1849   }
1850   const char *dep2str(Id id) {
1851     return pool_dep2str($self, id);
1852   }
1853   Id rel2id(Id name, Id evr, int flags, bool create=1) {
1854     return pool_rel2id($self, name, evr, flags, create);
1855   }
1856   Id id2langid(Id id, const char *lang, bool create=1) {
1857     return pool_id2langid($self, id, lang, create);
1858   }
1859   void setarch(const char *arch = 0) {
1860     struct utsname un;
1861     if (!arch) {
1862       if (uname(&un)) {
1863         perror("uname");
1864         return;
1865       }
1866       arch = un.machine;
1867     }
1868     pool_setarch($self, arch);
1869   }
1870   Repo *add_repo(const char *name) {
1871     return repo_create($self, name);
1872   }
1873   const char *lookup_str(Id entry, Id keyname) {
1874     return pool_lookup_str($self, entry, keyname);
1875   }
1876   Id lookup_id(Id entry, Id keyname) {
1877     return pool_lookup_id($self, entry, keyname);
1878   }
1879   unsigned long long lookup_num(Id entry, Id keyname, unsigned long long notfound = 0) {
1880     return pool_lookup_num($self, entry, keyname, notfound);
1881   }
1882   bool lookup_void(Id entry, Id keyname) {
1883     return pool_lookup_void($self, entry, keyname);
1884   }
1885   %newobject lookup_checksum;
1886   Chksum *lookup_checksum(Id entry, Id keyname) {
1887     Id type = 0;
1888     const unsigned char *b = pool_lookup_bin_checksum($self, entry, keyname, &type);
1889     return solv_chksum_create_from_bin(type, b);
1890   }
1891
1892   %newobject Dataiterator;
1893   Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
1894     return new_Dataiterator($self, 0, 0, key, match, flags);
1895   }
1896   %newobject Dataiterator_solvid;
1897   Dataiterator *Dataiterator_solvid(Id p, Id key, const char *match = 0, int flags = 0) {
1898     return new_Dataiterator($self, 0, p, key, match, flags);
1899   }
1900   const char *solvid2str(Id solvid) {
1901     return pool_solvid2str($self, solvid);
1902   }
1903   void addfileprovides() {
1904     pool_addfileprovides($self);
1905   }
1906   Queue addfileprovides_queue() {
1907     Queue r;
1908     queue_init(&r);
1909     pool_addfileprovides_queue($self, &r, 0);
1910     return r;
1911   }
1912   void createwhatprovides() {
1913     pool_createwhatprovides($self);
1914   }
1915
1916   %newobject id2solvable;
1917   XSolvable *id2solvable(Id id) {
1918     return new_XSolvable($self, id);
1919   }
1920   %newobject solvables;
1921   Pool_solvable_iterator * const solvables;
1922   %{
1923   SWIGINTERN Pool_solvable_iterator * Pool_solvables_get(Pool *pool) {
1924     return new_Pool_solvable_iterator(pool);
1925   }
1926   %}
1927   %newobject solvables_iter;
1928   Pool_solvable_iterator * solvables_iter() {
1929     return new_Pool_solvable_iterator($self);
1930   }
1931
1932   Repo *id2repo(Id id) {
1933     if (id < 1 || id >= $self->nrepos)
1934       return 0;
1935     return pool_id2repo($self, id);
1936   }
1937
1938   %newobject repos;
1939   Pool_repo_iterator * const repos;
1940   %{
1941   SWIGINTERN Pool_repo_iterator * Pool_repos_get(Pool *pool) {
1942     return new_Pool_repo_iterator(pool);
1943   }
1944   %}
1945   %newobject repos_iter;
1946   Pool_repo_iterator * repos_iter() {
1947     return new_Pool_repo_iterator($self);
1948   }
1949
1950   Repo *installed;
1951   const char * const errstr;
1952   %{
1953   SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
1954     pool_set_installed(pool, installed);
1955   }
1956   SWIGINTERN Repo *Pool_installed_get(Pool *pool) {
1957     return pool->installed;
1958   }
1959   SWIGINTERN const char *Pool_errstr_get(Pool *pool) {
1960     return pool_errstr(pool);
1961   }
1962   %}
1963
1964   Queue matchprovidingids(const char *match, int flags) {
1965     Pool *pool = $self;
1966     Queue q;
1967     Id id;
1968     queue_init(&q);
1969     if (!flags) {
1970       for (id = 1; id < pool->ss.nstrings; id++)
1971         if (pool->whatprovides[id])
1972           queue_push(&q, id);
1973     } else {
1974       Datamatcher ma;
1975       if (!datamatcher_init(&ma, match, flags)) {
1976         for (id = 1; id < pool->ss.nstrings; id++)
1977           if (pool->whatprovides[id] && datamatcher_match(&ma, pool_id2str(pool, id)))
1978             queue_push(&q, id);
1979         datamatcher_free(&ma);
1980       }
1981     }
1982     return q;
1983   }
1984
1985   %newobject Job;
1986   Job *Job(int how, Id what) {
1987     return new_Job($self, how, what);
1988   }
1989
1990   %typemap(out) Queue whatprovides Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
1991   %newobject whatprovides;
1992   Queue whatprovides(DepId dep) {
1993     Pool *pool = $self;
1994     Queue q;
1995     Id p, pp;
1996     queue_init(&q);
1997     FOR_PROVIDES(p, pp, dep)
1998       queue_push(&q, p);
1999     return q;
2000   }
2001   %typemap(out) Queue best_solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
2002   %newobject best_solvables;
2003   Queue best_solvables(Queue solvables, int flags=0) {
2004     Queue q;
2005     queue_init_clone(&q, &solvables);
2006     pool_best_solvables($self, &q, flags);
2007     return q;
2008   }
2009
2010   Id towhatprovides(Queue q) {
2011     return pool_queuetowhatprovides($self, &q);
2012   }
2013
2014   void set_namespaceproviders(DepId ns, DepId evr, bool value=1) {
2015     Id dep = pool_rel2id($self, ns, evr, REL_NAMESPACE, 1);
2016     pool_set_whatprovides($self, dep, value ? 2 : 1);
2017   }
2018
2019   void flush_namespaceproviders(DepId ns, DepId evr) {
2020     pool_flush_namespaceproviders($self, ns, evr);
2021   }
2022
2023   %typemap(out) Queue whatcontainsdep Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
2024   %newobject whatcontainsdep;
2025   Queue whatcontainsdep(Id keyname, DepId dep, Id marker = -1) {
2026     Queue q;
2027     queue_init(&q);
2028     pool_whatcontainsdep($self, keyname, dep, &q, marker);
2029     return q;
2030   }
2031
2032   %typemap(out) Queue whatmatchesdep Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
2033   %newobject whatmatchesdep;
2034   Queue whatmatchesdep(Id keyname, DepId dep, Id marker = -1) {
2035     Queue q;
2036     queue_init(&q);
2037     pool_whatmatchesdep($self, keyname, dep, &q, marker);
2038     return q;
2039   }
2040
2041   %typemap(out) Queue whatmatchessolvable Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
2042   %newobject whatmatchessolvable;
2043   Queue whatmatchessolvable(Id keyname, XSolvable *pool_solvable, Id marker = -1) {
2044     Queue q;
2045     queue_init(&q);
2046     pool_whatmatchessolvable($self, keyname, pool_solvable->id, &q, marker);
2047     return q;
2048   }
2049
2050 #ifdef SWIGRUBY
2051   %rename("isknownarch?") isknownarch;
2052 #endif
2053   bool isknownarch(DepId id) {
2054     Pool *pool = $self;
2055     if (!id || id == ID_EMPTY)
2056       return 0;
2057     if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
2058       return 1;
2059     if (pool->id2arch && pool_arch2score(pool, id) == 0)
2060       return 0;
2061     return 1;
2062   }
2063
2064   %newobject Solver;
2065   Solver *Solver() {
2066     return solver_create($self);
2067   }
2068
2069   %newobject Selection;
2070   Selection *Selection() {
2071     return new_Selection($self);
2072   }
2073   %newobject Selection_all;
2074   Selection *Selection_all(int setflags=0) {
2075     Selection *sel = new_Selection($self);
2076     queue_push2(&sel->q, SOLVER_SOLVABLE_ALL | setflags, 0);
2077     return sel;
2078   }
2079   %newobject select;
2080   Selection *select(const char *name, int flags) {
2081     Selection *sel = new_Selection($self);
2082     sel->flags = selection_make($self, &sel->q, name, flags);
2083     return sel;
2084   }
2085
2086   %newobject matchdeps;
2087   Selection *matchdeps(const char *name, int flags, Id keyname, Id marker = -1) {
2088     Selection *sel = new_Selection($self);
2089     sel->flags = selection_make_matchdeps($self, &sel->q, name, flags, keyname, marker);
2090     return sel;
2091   }
2092
2093   %newobject matchdepid;
2094   Selection *matchdepid(DepId dep, int flags, Id keyname, Id marker = -1) {
2095     Selection *sel = new_Selection($self);
2096     sel->flags = selection_make_matchdepid($self, &sel->q, dep, flags, keyname, marker);
2097     return sel;
2098   }
2099
2100   %newobject matchsolvable;
2101   Selection *matchsolvable(XSolvable *solvable, int flags, Id keyname, Id marker = -1) {
2102     Selection *sel = new_Selection($self);
2103     sel->flags = selection_make_matchsolvable($self, &sel->q, solvable->id, flags, keyname, marker);
2104     return sel;
2105   }
2106
2107   Queue get_considered_list() {
2108     Queue q;
2109     queue_init(&q);
2110     int i;
2111     for (i = 2; i < $self->nsolvables; i++) {
2112       if ($self->solvables[i].repo && (!$self->considered || MAPTST($self->considered, i)))
2113         queue_push(&q, i);
2114     }
2115     return q;
2116   }
2117
2118   Queue get_disabled_list() {
2119     Queue q;
2120     queue_init(&q);
2121     int i;
2122     for (i = 2; i < $self->nsolvables; i++) {
2123       if ($self->solvables[i].repo && ($self->considered && !MAPTST($self->considered, i)))
2124         queue_push(&q, i);
2125     }
2126     return q;
2127   }
2128
2129   void set_considered_list(Queue q) {
2130     int i;
2131     Id p;
2132     if (!$self->considered) {
2133       $self->considered = solv_calloc(1, sizeof(Map));
2134       map_init($self->considered, $self->nsolvables);
2135     }
2136     map_empty($self->considered);
2137     MAPSET($self->considered, 1);
2138     for (i = 0; i < q.count; i++) {
2139       p = q.elements[i];
2140       if (p > 0 && p < $self->nsolvables)
2141         MAPSET($self->considered, p);
2142     }
2143   }
2144
2145   void set_disabled_list(Queue q) {
2146     int i;
2147     Id p;
2148     if (!q.count) {
2149       if ($self->considered) {
2150         map_free($self->considered);
2151         $self->considered = solv_free($self->considered);
2152       }
2153       return;
2154     }
2155     if (!$self->considered) {
2156       $self->considered = solv_calloc(1, sizeof(Map));
2157       map_init($self->considered, $self->nsolvables);
2158     }
2159     map_setall($self->considered);
2160     for (i = 0; i < q.count; i++) {
2161       p = q.elements[i];
2162       if (p > 0 && p < $self->nsolvables)
2163         MAPCLR($self->considered, p);
2164     }
2165   }
2166
2167   void setpooljobs(Queue solvejobs) {
2168     queue_free(&$self->pooljobs);
2169     queue_init_clone(&$self->pooljobs, &solvejobs);
2170   }
2171   %typemap(out) Queue getpooljobs Queue2Array(Job *, 2, new_Job(arg1, id, idp[1]));
2172   %newobject getpooljobs;
2173   Queue getpooljobs() {
2174     Queue q;
2175     queue_init_clone(&q, &$self->pooljobs);
2176     return q;
2177   }
2178
2179 }
2180
2181 %extend Repo {
2182   static const int REPO_REUSE_REPODATA = REPO_REUSE_REPODATA;
2183   static const int REPO_NO_INTERNALIZE = REPO_NO_INTERNALIZE;
2184   static const int REPO_LOCALPOOL = REPO_LOCALPOOL;
2185   static const int REPO_USE_LOADING = REPO_USE_LOADING;
2186   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
2187   static const int REPO_USE_ROOTDIR = REPO_USE_ROOTDIR;
2188   static const int REPO_NO_LOCATION = REPO_NO_LOCATION;
2189   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
2190 #ifdef ENABLE_SUSEREPO
2191   static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES;     /* repo_susetags */
2192 #endif
2193
2194   void free(bool reuseids = 0) {
2195     appdata_clr_helper(&$self->appdata);
2196     repo_free($self, reuseids);
2197   }
2198   void empty(bool reuseids = 0) {
2199     repo_empty($self, reuseids);
2200   }
2201 #ifdef SWIGRUBY
2202   %rename("isempty?") isempty;
2203 #endif
2204   bool isempty() {
2205     return !$self->nsolvables;
2206   }
2207
2208   AppObjectPtr appdata;
2209   %{
2210   SWIGINTERN void Repo_appdata_set(Repo *repo, AppObjectPtr appdata) {
2211     appdata_set_helper(&repo->appdata, appdata);
2212   }
2213   SWIGINTERN AppObjectPtr Repo_appdata_get(Repo *repo) {
2214     return appdata_get_helper(repo->appdata);
2215   }
2216   %}
2217
2218   bool add_solv(const char *name, int flags = 0) {
2219     FILE *fp = fopen(name, "r");
2220     int r;
2221     if (!fp)
2222       return 0;
2223     r = repo_add_solv($self, fp, flags);
2224     fclose(fp);
2225     return r == 0;
2226   }
2227   bool add_solv(FILE *fp, int flags = 0) {
2228     return repo_add_solv($self, fp, flags) == 0;
2229   }
2230
2231   %newobject add_solvable;
2232   XSolvable *add_solvable() {
2233     Id solvid = repo_add_solvable($self);
2234     return new_XSolvable($self->pool, solvid);
2235   }
2236
2237 #ifdef ENABLE_RPMDB
2238   bool add_rpmdb(int flags = 0) {
2239     return repo_add_rpmdb($self, 0, flags) == 0;
2240   }
2241   bool add_rpmdb_reffp(FILE *reffp, int flags = 0) {
2242     return repo_add_rpmdb_reffp($self, reffp, flags) == 0;
2243   }
2244 #endif
2245 #ifdef ENABLE_RPMPKG
2246   %newobject add_rpm;
2247   XSolvable *add_rpm(const char *name, int flags = 0) {
2248     return new_XSolvable($self->pool, repo_add_rpm($self, name, flags));
2249   }
2250 #endif
2251 #ifdef ENABLE_PUBKEY
2252 #ifdef ENABLE_RPMDB
2253   bool add_rpmdb_pubkeys(int flags = 0) {
2254     return repo_add_rpmdb_pubkeys($self, flags) == 0;
2255   }
2256 #endif
2257   %newobject add_pubkey;
2258   XSolvable *add_pubkey(const char *keyfile, int flags = 0) {
2259     return new_XSolvable($self->pool, repo_add_pubkey($self, keyfile, flags));
2260   }
2261   bool add_keyring(FILE *fp, int flags = 0) {
2262     return repo_add_keyring($self, fp, flags);
2263   }
2264   bool add_keydir(const char *keydir, const char *suffix, int flags = 0) {
2265     return repo_add_keydir($self, keydir, suffix, flags);
2266   }
2267 #endif
2268 #ifdef ENABLE_RPMMD
2269   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
2270     return repo_add_rpmmd($self, fp, language, flags) == 0;
2271   }
2272   bool add_repomdxml(FILE *fp, int flags = 0) {
2273     return repo_add_repomdxml($self, fp, flags) == 0;
2274   }
2275   bool add_updateinfoxml(FILE *fp, int flags = 0) {
2276     return repo_add_updateinfoxml($self, fp, flags) == 0;
2277   }
2278   bool add_deltainfoxml(FILE *fp, int flags = 0) {
2279     return repo_add_deltainfoxml($self, fp, flags) == 0;
2280   }
2281 #endif
2282 #ifdef ENABLE_DEBIAN
2283   bool add_debdb(int flags = 0) {
2284     return repo_add_debdb($self, flags) == 0;
2285   }
2286   bool add_debpackages(FILE *fp, int flags = 0) {
2287     return repo_add_debpackages($self, fp, flags) == 0;
2288   }
2289   %newobject add_deb;
2290   XSolvable *add_deb(const char *name, int flags = 0) {
2291     return new_XSolvable($self->pool, repo_add_deb($self, name, flags));
2292   }
2293 #endif
2294 #ifdef ENABLE_SUSEREPO
2295   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
2296     return repo_add_susetags($self, fp, defvendor, language, flags) == 0;
2297   }
2298   bool add_content(FILE *fp, int flags = 0) {
2299     return repo_add_content($self, fp, flags) == 0;
2300   }
2301   bool add_products(const char *proddir, int flags = 0) {
2302     return repo_add_products($self, proddir, flags) == 0;
2303   }
2304 #endif
2305 #ifdef ENABLE_MDKREPO
2306   bool add_mdk(FILE *fp, int flags = 0) {
2307     return repo_add_mdk($self, fp, flags) == 0;
2308   }
2309   bool add_mdk_info(FILE *fp, int flags = 0) {
2310     return repo_add_mdk_info($self, fp, flags) == 0;
2311   }
2312 #endif
2313 #ifdef ENABLE_ARCHREPO
2314   bool add_arch_repo(FILE *fp, int flags = 0) {
2315     return repo_add_arch_repo($self, fp, flags) == 0;
2316   }
2317   bool add_arch_local(const char *dir, int flags = 0) {
2318     return repo_add_arch_local($self, dir, flags) == 0;
2319   }
2320   %newobject add_arch_pkg;
2321   XSolvable *add_arch_pkg(const char *name, int flags = 0) {
2322     return new_XSolvable($self->pool, repo_add_arch_pkg($self, name, flags));
2323   }
2324 #endif
2325 #ifdef SUSE
2326   bool add_autopattern(int flags = 0) {
2327     return repo_add_autopattern($self, flags) == 0;
2328   }
2329 #endif
2330   void internalize() {
2331     repo_internalize($self);
2332   }
2333   bool write(FILE *fp) {
2334     return repo_write($self, fp) == 0;
2335   }
2336   /* HACK, remove if no longer needed! */
2337   bool write_first_repodata(FILE *fp) {
2338     int oldnrepodata = $self->nrepodata;
2339     int res;
2340     $self->nrepodata = oldnrepodata > 2 ? 2 : oldnrepodata;
2341     res = repo_write($self, fp);
2342     $self->nrepodata = oldnrepodata;
2343     return res == 0;
2344   }
2345
2346   %newobject Dataiterator;
2347   Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
2348     return new_Dataiterator($self->pool, $self, 0, key, match, flags);
2349   }
2350   %newobject Dataiterator_meta;
2351   Dataiterator *Dataiterator_meta(Id key, const char *match = 0, int flags = 0) {
2352     return new_Dataiterator($self->pool, $self, SOLVID_META, key, match, flags);
2353   }
2354
2355   Id const id;
2356   %{
2357   SWIGINTERN Id Repo_id_get(Repo *repo) {
2358     return repo->repoid;
2359   }
2360   %}
2361   %newobject solvables;
2362   Repo_solvable_iterator * const solvables;
2363   %{
2364   SWIGINTERN Repo_solvable_iterator * Repo_solvables_get(Repo *repo) {
2365     return new_Repo_solvable_iterator(repo);
2366   }
2367   %}
2368   %newobject meta;
2369   Datapos * const meta;
2370   %{
2371   SWIGINTERN Datapos * Repo_meta_get(Repo *repo) {
2372     Datapos *pos = solv_calloc(1, sizeof(*pos));
2373     pos->solvid = SOLVID_META;
2374     pos->repo = repo;
2375     return pos;
2376   }
2377   %}
2378
2379   %newobject solvables_iter;
2380   Repo_solvable_iterator *solvables_iter() {
2381     return new_Repo_solvable_iterator($self);
2382   }
2383
2384   %newobject add_repodata;
2385   XRepodata *add_repodata(int flags = 0) {
2386     Repodata *rd = repo_add_repodata($self, flags);
2387     return new_XRepodata($self, rd->repodataid);
2388   }
2389
2390   void create_stubs() {
2391     Repodata *data;
2392     if (!$self->nrepodata)
2393       return;
2394     data = repo_id2repodata($self, $self->nrepodata - 1);
2395     if (data->state != REPODATA_STUB)
2396       (void)repodata_create_stubs(data);
2397   }
2398 #ifdef SWIGRUBY
2399   %rename("iscontiguous?") iscontiguous;
2400 #endif
2401   bool iscontiguous() {
2402     int i;
2403     for (i = $self->start; i < $self->end; i++)
2404       if ($self->pool->solvables[i].repo != $self)
2405         return 0;
2406     return 1;
2407   }
2408   %newobject first_repodata;
2409   XRepodata *first_repodata() {
2410     Repodata *data;
2411     int i;
2412     if ($self->nrepodata < 2)
2413       return 0;
2414     /* make sure all repodatas but the first are extensions */
2415     data = repo_id2repodata($self, 1);
2416     if (data->loadcallback)
2417        return 0;
2418     for (i = 2; i < $self->nrepodata; i++)
2419       {
2420         data = repo_id2repodata($self, i);
2421         if (!data->loadcallback)
2422           return 0;       /* oops, not an extension */
2423       }
2424     return new_XRepodata($self, 1);
2425   }
2426
2427   %newobject Selection;
2428   Selection *Selection(int setflags=0) {
2429     Selection *sel = new_Selection($self->pool);
2430     setflags |= SOLVER_SETREPO;
2431     queue_push2(&sel->q, SOLVER_SOLVABLE_REPO | setflags, $self->repoid);
2432     return sel;
2433   }
2434
2435 #ifdef ENABLE_PUBKEY
2436   %newobject find_pubkey;
2437   XSolvable *find_pubkey(const char *keyid) {
2438     return new_XSolvable($self->pool, repo_find_pubkey($self, keyid));
2439   }
2440 #endif
2441
2442   Repo *createshadow(const char *name) {
2443     Repo *repo = repo_create($self->pool, name);
2444     if ($self->idarraysize) {
2445       repo_reserve_ids(repo, 0, $self->idarraysize);
2446       memcpy(repo->idarraydata, $self->idarraydata, sizeof(Id) * $self->idarraysize);
2447       repo->idarraysize = $self->idarraysize;
2448     }
2449     repo->start = $self->start;
2450     repo->end = $self->end;
2451     repo->nsolvables = $self->nsolvables;
2452     return repo;
2453   }
2454
2455   void moveshadow(Queue q) {
2456     Pool *pool = $self->pool;
2457     int i;
2458     for (i = 0; i < q.count; i++) {
2459       Solvable *s;
2460       Id p = q.elements[i];
2461       if (p < $self->start || p >= $self->end)
2462         continue;
2463       s = pool->solvables + p;
2464       if ($self->idarraysize != s->repo->idarraysize)
2465         continue;
2466       s->repo = $self;
2467     }
2468   }
2469
2470 #if defined(SWIGTCL)
2471   %rename("==") __eq__;
2472 #endif
2473   bool __eq__(Repo *repo) {
2474     return $self == repo;
2475   }
2476 #if defined(SWIGTCL)
2477   %rename("!=") __ne__;
2478 #endif
2479   bool __ne__(Repo *repo) {
2480     return $self != repo;
2481   }
2482 #if defined(SWIGPYTHON)
2483   int __hash__() {
2484     return $self->repoid;
2485   }
2486 #endif
2487 #if defined(SWIGPERL) || defined(SWIGTCL)
2488   %rename("str") __str__;
2489 #endif
2490   %newobject __str__;
2491   const char *__str__() {
2492     char buf[20];
2493     if ($self->name)
2494       return solv_strdup($self->name);
2495     sprintf(buf, "Repo#%d", $self->repoid);
2496     return solv_strdup(buf);
2497   }
2498 #if defined(SWIGPERL) || defined(SWIGTCL)
2499   %rename("repr") __repr__;
2500 #endif
2501   %newobject __repr__;
2502   const char *__repr__() {
2503     char buf[20];
2504     if ($self->name)
2505       {
2506         sprintf(buf, "<Repo #%d ", $self->repoid);
2507         return solv_dupjoin(buf, $self->name, ">");
2508       }
2509     sprintf(buf, "<Repo #%d>", $self->repoid);
2510     return solv_strdup(buf);
2511   }
2512 }
2513
2514 %extend Dataiterator {
2515   static const int SEARCH_STRING = SEARCH_STRING;
2516   static const int SEARCH_STRINGSTART = SEARCH_STRINGSTART;
2517   static const int SEARCH_STRINGEND = SEARCH_STRINGEND;
2518   static const int SEARCH_SUBSTRING = SEARCH_SUBSTRING;
2519   static const int SEARCH_GLOB = SEARCH_GLOB;
2520   static const int SEARCH_REGEX = SEARCH_REGEX;
2521   static const int SEARCH_NOCASE = SEARCH_NOCASE;
2522   static const int SEARCH_FILES = SEARCH_FILES;
2523   static const int SEARCH_COMPLETE_FILELIST = SEARCH_COMPLETE_FILELIST;
2524   static const int SEARCH_CHECKSUMS = SEARCH_CHECKSUMS;
2525
2526   Dataiterator(Pool *pool, Repo *repo, Id p, Id key, const char *match, int flags) {
2527     Dataiterator *di = solv_calloc(1, sizeof(*di));
2528     dataiterator_init(di, pool, repo, p, key, match, flags);
2529     return di;
2530   }
2531   ~Dataiterator() {
2532     dataiterator_free($self);
2533     solv_free($self);
2534   }
2535 #if defined(SWIGPYTHON)
2536   %pythoncode {
2537     def __iter__(self): return self
2538   }
2539 #ifndef PYTHON3
2540   %rename("next") __next__();
2541 #endif
2542   %exception __next__ {
2543     $action
2544     if (!result) {
2545       PyErr_SetString(PyExc_StopIteration,"no more matches");
2546       return NULL;
2547     }
2548   }
2549 #endif
2550 #ifdef SWIGPERL
2551   perliter(solv::Dataiterator)
2552 #endif
2553   %newobject __next__;
2554   Datamatch *__next__() {
2555     Dataiterator *ndi;
2556     if (!dataiterator_step($self)) {
2557       return 0;
2558     }
2559     ndi = solv_calloc(1, sizeof(*ndi));
2560     dataiterator_init_clone(ndi, $self);
2561     dataiterator_strdup(ndi);
2562     return ndi;
2563   }
2564 #ifdef SWIGRUBY
2565   void each() {
2566     Datamatch *d;
2567     while ((d = Dataiterator___next__($self)) != 0) {
2568       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(d), SWIGTYPE_p_Datamatch, SWIG_POINTER_OWN | 0));
2569     }
2570   }
2571 #endif
2572   void prepend_keyname(Id key) {
2573     dataiterator_prepend_keyname($self, key);
2574   }
2575   void skip_solvable() {
2576     dataiterator_skip_solvable($self);
2577   }
2578 }
2579
2580 %extend Datapos {
2581   Id lookup_id(Id keyname) {
2582     Pool *pool = $self->repo->pool;
2583     Datapos oldpos = pool->pos;
2584     Id r;
2585     pool->pos = *$self;
2586     r = pool_lookup_id(pool, SOLVID_POS, keyname);
2587     pool->pos = oldpos;
2588     return r;
2589   }
2590   const char *lookup_str(Id keyname) {
2591     Pool *pool = $self->repo->pool;
2592     Datapos oldpos = pool->pos;
2593     const char *r;
2594     pool->pos = *$self;
2595     r = pool_lookup_str(pool, SOLVID_POS, keyname);
2596     pool->pos = oldpos;
2597     return r;
2598   }
2599   unsigned long long lookup_num(Id keyname, unsigned long long notfound = 0) {
2600     Pool *pool = $self->repo->pool;
2601     Datapos oldpos = pool->pos;
2602     unsigned long long r;
2603     pool->pos = *$self;
2604     r = pool_lookup_num(pool, SOLVID_POS, keyname, notfound);
2605     pool->pos = oldpos;
2606     return r;
2607   }
2608   bool lookup_void(Id keyname) {
2609     Pool *pool = $self->repo->pool;
2610     Datapos oldpos = pool->pos;
2611     int r;
2612     pool->pos = *$self;
2613     r = pool_lookup_void(pool, SOLVID_POS, keyname);
2614     pool->pos = oldpos;
2615     return r;
2616   }
2617   %newobject lookup_checksum;
2618   Chksum *lookup_checksum(Id keyname) {
2619     Pool *pool = $self->repo->pool;
2620     Datapos oldpos = pool->pos;
2621     Id type = 0;
2622     const unsigned char *b;
2623     pool->pos = *$self;
2624     b = pool_lookup_bin_checksum(pool, SOLVID_POS, keyname, &type);
2625     pool->pos = oldpos;
2626     return solv_chksum_create_from_bin(type, b);
2627   }
2628   const char *lookup_deltaseq() {
2629     Pool *pool = $self->repo->pool;
2630     Datapos oldpos = pool->pos;
2631     const char *seq;
2632     pool->pos = *$self;
2633     seq = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NAME);
2634     if (seq) {
2635       seq = pool_tmpjoin(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_EVR));
2636       seq = pool_tmpappend(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NUM));
2637     }
2638     pool->pos = oldpos;
2639     return seq;
2640   }
2641   const char *lookup_deltalocation(unsigned int *OUTPUT) {
2642     Pool *pool = $self->repo->pool;
2643     Datapos oldpos = pool->pos;
2644     const char *loc;
2645     pool->pos = *$self;
2646     loc = pool_lookup_deltalocation(pool, SOLVID_POS, OUTPUT);
2647     pool->pos = oldpos;
2648     return loc;
2649   }
2650   Queue lookup_idarray(Id keyname) {
2651     Pool *pool = $self->repo->pool;
2652     Datapos oldpos = pool->pos;
2653     Queue r;
2654     queue_init(&r);
2655     pool->pos = *$self;
2656     pool_lookup_idarray(pool, SOLVID_POS, keyname, &r);
2657     pool->pos = oldpos;
2658     return r;
2659   }
2660   %newobject Dataiterator;
2661   Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
2662     Pool *pool = $self->repo->pool;
2663     Datapos oldpos = pool->pos;
2664     Dataiterator *di;
2665     pool->pos = *$self;
2666     di = new_Dataiterator(pool, 0, SOLVID_POS, key, match, flags);
2667     pool->pos = oldpos;
2668     return di;
2669   }
2670 }
2671
2672 %extend Datamatch {
2673   ~Datamatch() {
2674     dataiterator_free($self);
2675     solv_free($self);
2676   }
2677   %newobject solvable;
2678   XSolvable * const solvable;
2679   Id const key_id;
2680   const char * const key_idstr;
2681   Id const type_id;
2682   const char * const type_idstr;
2683   Id const id;
2684   const char * const idstr;
2685   const char * const str;
2686   BinaryBlob const binary;
2687   unsigned long long const num;
2688   unsigned int const num2;
2689   %{
2690   SWIGINTERN XSolvable *Datamatch_solvable_get(Dataiterator *di) {
2691     return new_XSolvable(di->pool, di->solvid);
2692   }
2693   SWIGINTERN Id Datamatch_key_id_get(Dataiterator *di) {
2694     return di->key->name;
2695   }
2696   SWIGINTERN const char *Datamatch_key_idstr_get(Dataiterator *di) {
2697     return pool_id2str(di->pool, di->key->name);
2698   }
2699   SWIGINTERN Id Datamatch_type_id_get(Dataiterator *di) {
2700     return di->key->type;
2701   }
2702   SWIGINTERN const char *Datamatch_type_idstr_get(Dataiterator *di) {
2703     return pool_id2str(di->pool, di->key->type);
2704   }
2705   SWIGINTERN Id Datamatch_id_get(Dataiterator *di) {
2706     return di->kv.id;
2707   }
2708   SWIGINTERN const char *Datamatch_idstr_get(Dataiterator *di) {
2709    if (di->data && (di->key->type == REPOKEY_TYPE_DIR || di->key->type == REPOKEY_TYPE_DIRSTRARRAY || di->key->type == REPOKEY_TYPE_DIRNUMNUMARRAY))
2710       return repodata_dir2str(di->data,  di->kv.id, 0);
2711     if (di->data && di->data->localpool)
2712       return stringpool_id2str(&di->data->spool, di->kv.id);
2713     return pool_id2str(di->pool, di->kv.id);
2714   }
2715   SWIGINTERN const char * const Datamatch_str_get(Dataiterator *di) {
2716     return di->kv.str;
2717   }
2718   SWIGINTERN BinaryBlob Datamatch_binary_get(Dataiterator *di) {
2719     BinaryBlob bl;
2720     bl.data = 0;
2721     bl.len = 0;
2722     if (di->key->type == REPOKEY_TYPE_BINARY)
2723       {
2724         bl.data = di->kv.str;
2725         bl.len = di->kv.num;
2726       }
2727     else if ((bl.len = solv_chksum_len(di->key->type)) != 0)
2728       bl.data = di->kv.str;
2729     return bl;
2730   }
2731   SWIGINTERN unsigned long long Datamatch_num_get(Dataiterator *di) {
2732    if (di->key->type == REPOKEY_TYPE_NUM)
2733      return SOLV_KV_NUM64(&di->kv);
2734    return di->kv.num;
2735   }
2736   SWIGINTERN unsigned int Datamatch_num2_get(Dataiterator *di) {
2737     return di->kv.num2;
2738   }
2739   %}
2740   %newobject pos;
2741   Datapos *pos() {
2742     Pool *pool = $self->pool;
2743     Datapos *pos, oldpos = pool->pos;
2744     dataiterator_setpos($self);
2745     pos = solv_calloc(1, sizeof(*pos));
2746     *pos = pool->pos;
2747     pool->pos = oldpos;
2748     return pos;
2749   }
2750   %newobject parentpos;
2751   Datapos *parentpos() {
2752     Pool *pool = $self->pool;
2753     Datapos *pos, oldpos = pool->pos;
2754     dataiterator_setpos_parent($self);
2755     pos = solv_calloc(1, sizeof(*pos));
2756     *pos = pool->pos;
2757     pool->pos = oldpos;
2758     return pos;
2759   }
2760 #if defined(SWIGPERL)
2761   /* cannot use str here because swig reports a bogus conflict... */
2762   %rename("stringify") __str__;
2763   %perlcode {
2764     *solv::Datamatch::str = *solvc::Datamatch_stringify;
2765   }
2766 #endif
2767 #if defined(SWIGTCL)
2768   %rename("stringify") __str__;
2769 #endif
2770   const char *__str__() {
2771     KeyValue kv = $self->kv;
2772     const char *str = repodata_stringify($self->pool, $self->data, $self->key, &kv, SEARCH_FILES | SEARCH_CHECKSUMS);
2773     return str ? str : "";
2774   }
2775 }
2776
2777 %extend Pool_solvable_iterator {
2778   Pool_solvable_iterator(Pool *pool) {
2779     Pool_solvable_iterator *s;
2780     s = solv_calloc(1, sizeof(*s));
2781     s->pool = pool;
2782     return s;
2783   }
2784 #if defined(SWIGPYTHON)
2785   %pythoncode {
2786     def __iter__(self): return self
2787   }
2788 #ifndef PYTHON3
2789   %rename("next") __next__();
2790 #endif
2791   %exception __next__ {
2792     $action
2793     if (!result) {
2794       PyErr_SetString(PyExc_StopIteration,"no more matches");
2795       return NULL;
2796     }
2797   }
2798 #endif
2799 #ifdef SWIGPERL
2800   perliter(solv::Pool_solvable_iterator)
2801 #endif
2802   %newobject __next__;
2803   XSolvable *__next__() {
2804     Pool *pool = $self->pool;
2805     if ($self->id >= pool->nsolvables)
2806       return 0;
2807     while (++$self->id < pool->nsolvables)
2808       if (pool->solvables[$self->id].repo)
2809         return new_XSolvable(pool, $self->id);
2810     return 0;
2811   }
2812 #ifdef SWIGRUBY
2813   void each() {
2814     XSolvable *n;
2815     while ((n = Pool_solvable_iterator___next__($self)) != 0) {
2816       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
2817     }
2818   }
2819 #endif
2820   %newobject __getitem__;
2821   XSolvable *__getitem__(Id key) {
2822     Pool *pool = $self->pool;
2823     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo)
2824       return new_XSolvable(pool, key);
2825     return 0;
2826   }
2827   int __len__() {
2828     return $self->pool->nsolvables;
2829   }
2830 }
2831
2832 %extend Pool_repo_iterator {
2833   Pool_repo_iterator(Pool *pool) {
2834     Pool_repo_iterator *s;
2835     s = solv_calloc(1, sizeof(*s));
2836     s->pool = pool;
2837     return s;
2838   }
2839 #if defined(SWIGPYTHON)
2840   %pythoncode {
2841     def __iter__(self): return self
2842   }
2843 #ifndef PYTHON3
2844   %rename("next") __next__();
2845 #endif
2846   %exception __next__ {
2847     $action
2848     if (!result) {
2849       PyErr_SetString(PyExc_StopIteration,"no more matches");
2850       return NULL;
2851     }
2852   }
2853 #endif
2854 #ifdef SWIGPERL
2855   perliter(solv::Pool_repo_iterator)
2856 #endif
2857   Repo *__next__() {
2858     Pool *pool = $self->pool;
2859     if ($self->id >= pool->nrepos)
2860       return 0;
2861     while (++$self->id < pool->nrepos) {
2862       Repo *r = pool_id2repo(pool, $self->id);
2863       if (r)
2864         return r;
2865     }
2866     return 0;
2867   }
2868 #ifdef SWIGRUBY
2869   void each() {
2870     Repo *n;
2871     while ((n = Pool_repo_iterator___next__($self)) != 0) {
2872       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_Repo, 0 | 0));
2873     }
2874   }
2875 #endif
2876   Repo *__getitem__(Id key) {
2877     Pool *pool = $self->pool;
2878     if (key > 0 && key < pool->nrepos)
2879       return pool_id2repo(pool, key);
2880     return 0;
2881   }
2882   int __len__() {
2883     return $self->pool->nrepos;
2884   }
2885 }
2886
2887 %extend Repo_solvable_iterator {
2888   Repo_solvable_iterator(Repo *repo) {
2889     Repo_solvable_iterator *s;
2890     s = solv_calloc(1, sizeof(*s));
2891     s->repo = repo;
2892     return s;
2893   }
2894 #if defined(SWIGPYTHON)
2895   %pythoncode {
2896     def __iter__(self): return self
2897   }
2898 #ifndef PYTHON3
2899   %rename("next") __next__();
2900 #endif
2901   %exception __next__ {
2902     $action
2903     if (!result) {
2904       PyErr_SetString(PyExc_StopIteration,"no more matches");
2905       return NULL;
2906     }
2907   }
2908 #endif
2909 #ifdef SWIGPERL
2910   perliter(solv::Repo_solvable_iterator)
2911 #endif
2912   %newobject __next__;
2913   XSolvable *__next__() {
2914     Repo *repo = $self->repo;
2915     Pool *pool = repo->pool;
2916     if (repo->start > 0 && $self->id < repo->start)
2917       $self->id = repo->start - 1;
2918     if ($self->id >= repo->end)
2919       return 0;
2920     while (++$self->id < repo->end)
2921       if (pool->solvables[$self->id].repo == repo)
2922         return new_XSolvable(pool, $self->id);
2923     return 0;
2924   }
2925 #ifdef SWIGRUBY
2926   void each() {
2927     XSolvable *n;
2928     while ((n = Repo_solvable_iterator___next__($self)) != 0) {
2929       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
2930     }
2931   }
2932 #endif
2933   %newobject __getitem__;
2934   XSolvable *__getitem__(Id key) {
2935     Repo *repo = $self->repo;
2936     Pool *pool = repo->pool;
2937     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo == repo)
2938       return new_XSolvable(pool, key);
2939     return 0;
2940   }
2941   int __len__() {
2942     return $self->repo->pool->nsolvables;
2943   }
2944 }
2945
2946 %extend Dep {
2947   Dep(Pool *pool, Id id) {
2948     Dep *s;
2949     if (!id)
2950       return 0;
2951     s = solv_calloc(1, sizeof(*s));
2952     s->pool = pool;
2953     s->id = id;
2954     return s;
2955   }
2956   %newobject Rel;
2957   Dep *Rel(int flags, DepId evrid, bool create=1) {
2958     Id id = pool_rel2id($self->pool, $self->id, evrid, flags, create);
2959     if (!id)
2960       return 0;
2961     return new_Dep($self->pool, id);
2962   }
2963   %newobject Selection_name;
2964   Selection *Selection_name(int setflags=0) {
2965     Selection *sel = new_Selection($self->pool);
2966     if (ISRELDEP($self->id)) {
2967       Reldep *rd = GETRELDEP($self->pool, $self->id);
2968       if (rd->flags == REL_EQ) {
2969         setflags |= $self->pool->disttype == DISTTYPE_DEB || strchr(pool_id2str($self->pool, rd->evr), '-') != 0 ? SOLVER_SETEVR : SOLVER_SETEV;
2970         if (ISRELDEP(rd->name))
2971           rd = GETRELDEP($self->pool, rd->name);
2972       }
2973       if (rd->flags == REL_ARCH)
2974         setflags |= SOLVER_SETARCH;
2975     }
2976     queue_push2(&sel->q, SOLVER_SOLVABLE_NAME | setflags, $self->id);
2977     return sel;
2978   }
2979   %newobject Selection_provides;
2980   Selection *Selection_provides(int setflags=0) {
2981     Selection *sel = new_Selection($self->pool);
2982     if (ISRELDEP($self->id)) {
2983       Reldep *rd = GETRELDEP($self->pool, $self->id);
2984       if (rd->flags == REL_ARCH)
2985         setflags |= SOLVER_SETARCH;
2986     }
2987     queue_push2(&sel->q, SOLVER_SOLVABLE_PROVIDES | setflags, $self->id);
2988     return sel;
2989   }
2990   const char *str() {
2991     return pool_dep2str($self->pool, $self->id);
2992   }
2993 #if defined(SWIGTCL)
2994   %rename("==") __eq__;
2995 #endif
2996   bool __eq__(Dep *s) {
2997     return $self->pool == s->pool && $self->id == s->id;
2998   }
2999 #if defined(SWIGTCL)
3000   %rename("!=") __ne__;
3001 #endif
3002   bool __ne__(Dep *s) {
3003     return !Dep___eq__($self, s);
3004   }
3005 #if defined(SWIGPYTHON)
3006   int __hash__() {
3007     return $self->id;
3008   }
3009 #endif
3010 #if defined(SWIGPERL) || defined(SWIGTCL)
3011   %rename("str") __str__;
3012 #endif
3013   const char *__str__() {
3014     return pool_dep2str($self->pool, $self->id);
3015   }
3016 #if defined(SWIGPERL) || defined(SWIGTCL)
3017   %rename("repr") __repr__;
3018 #endif
3019   %newobject __repr__;
3020   const char *__repr__() {
3021     char buf[20];
3022     sprintf(buf, "<Id #%d ", $self->id);
3023     return solv_dupjoin(buf, pool_dep2str($self->pool, $self->id), ">");
3024   }
3025 }
3026
3027 %extend XSolvable {
3028   XSolvable(Pool *pool, Id id) {
3029     XSolvable *s;
3030     if (!id || id >= pool->nsolvables)
3031       return 0;
3032     s = solv_calloc(1, sizeof(*s));
3033     s->pool = pool;
3034     s->id = id;
3035     return s;
3036   }
3037   const char *str() {
3038     return pool_solvid2str($self->pool, $self->id);
3039   }
3040   const char *lookup_str(Id keyname) {
3041     return pool_lookup_str($self->pool, $self->id, keyname);
3042   }
3043   Id lookup_id(Id keyname) {
3044     return pool_lookup_id($self->pool, $self->id, keyname);
3045   }
3046   unsigned long long lookup_num(Id keyname, unsigned long long notfound = 0) {
3047     return pool_lookup_num($self->pool, $self->id, keyname, notfound);
3048   }
3049   bool lookup_void(Id keyname) {
3050     return pool_lookup_void($self->pool, $self->id, keyname);
3051   }
3052   %newobject lookup_checksum;
3053   Chksum *lookup_checksum(Id keyname) {
3054     Id type = 0;
3055     const unsigned char *b = pool_lookup_bin_checksum($self->pool, $self->id, keyname, &type);
3056     return solv_chksum_create_from_bin(type, b);
3057   }
3058   Queue lookup_idarray(Id keyname, Id marker = -1) {
3059     Solvable *s = $self->pool->solvables + $self->id;
3060     Queue r;
3061     queue_init(&r);
3062     solvable_lookup_deparray(s, keyname, &r, marker);
3063     return r;
3064   }
3065   %typemap(out) Queue lookup_deparray Queue2Array(Dep *, 1, new_Dep(arg1->pool, id));
3066   %newobject lookup_deparray;
3067   Queue lookup_deparray(Id keyname, Id marker = -1) {
3068     Solvable *s = $self->pool->solvables + $self->id;
3069     Queue r;
3070     queue_init(&r);
3071     solvable_lookup_deparray(s, keyname, &r, marker);
3072     return r;
3073   }
3074   const char *lookup_location(unsigned int *OUTPUT) {
3075     return solvable_lookup_location($self->pool->solvables + $self->id, OUTPUT);
3076   }
3077   const char *lookup_sourcepkg() {
3078     return solvable_lookup_sourcepkg($self->pool->solvables + $self->id);
3079   }
3080   %newobject Dataiterator;
3081   Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
3082     return new_Dataiterator($self->pool, 0, $self->id, key, match, flags);
3083   }
3084 #ifdef SWIGRUBY
3085   %rename("installable?") installable;
3086 #endif
3087   bool installable() {
3088     return pool_installable($self->pool, pool_id2solvable($self->pool, $self->id));
3089   }
3090 #ifdef SWIGRUBY
3091   %rename("isinstalled?") isinstalled;
3092 #endif
3093   bool isinstalled() {
3094     Pool *pool = $self->pool;
3095     return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed;
3096   }
3097
3098   const char *name;
3099   %{
3100     SWIGINTERN void XSolvable_name_set(XSolvable *xs, const char *name) {
3101       Pool *pool = xs->pool;
3102       pool->solvables[xs->id].name = pool_str2id(pool, name, 1);
3103     }
3104     SWIGINTERN const char *XSolvable_name_get(XSolvable *xs) {
3105       Pool *pool = xs->pool;
3106       return pool_id2str(pool, pool->solvables[xs->id].name);
3107     }
3108   %}
3109   Id nameid;
3110   %{
3111     SWIGINTERN void XSolvable_nameid_set(XSolvable *xs, Id nameid) {
3112       xs->pool->solvables[xs->id].name = nameid;
3113     }
3114     SWIGINTERN Id XSolvable_nameid_get(XSolvable *xs) {
3115       return xs->pool->solvables[xs->id].name;
3116     }
3117   %}
3118   const char *evr;
3119   %{
3120     SWIGINTERN void XSolvable_evr_set(XSolvable *xs, const char *evr) {
3121       Pool *pool = xs->pool;
3122       pool->solvables[xs->id].evr = pool_str2id(pool, evr, 1);
3123     }
3124     SWIGINTERN const char *XSolvable_evr_get(XSolvable *xs) {
3125       Pool *pool = xs->pool;
3126       return pool_id2str(pool, pool->solvables[xs->id].evr);
3127     }
3128   %}
3129   Id evrid;
3130   %{
3131     SWIGINTERN void XSolvable_evrid_set(XSolvable *xs, Id evrid) {
3132       xs->pool->solvables[xs->id].evr = evrid;
3133     }
3134     SWIGINTERN Id XSolvable_evrid_get(XSolvable *xs) {
3135       return xs->pool->solvables[xs->id].evr;
3136     }
3137   %}
3138   const char *arch;
3139   %{
3140     SWIGINTERN void XSolvable_arch_set(XSolvable *xs, const char *arch) {
3141       Pool *pool = xs->pool;
3142       pool->solvables[xs->id].arch = pool_str2id(pool, arch, 1);
3143     }
3144     SWIGINTERN const char *XSolvable_arch_get(XSolvable *xs) {
3145       Pool *pool = xs->pool;
3146       return pool_id2str(pool, pool->solvables[xs->id].arch);
3147     }
3148   %}
3149   Id archid;
3150   %{
3151     SWIGINTERN void XSolvable_archid_set(XSolvable *xs, Id archid) {
3152       xs->pool->solvables[xs->id].arch = archid;
3153     }
3154     SWIGINTERN Id XSolvable_archid_get(XSolvable *xs) {
3155       return xs->pool->solvables[xs->id].arch;
3156     }
3157   %}
3158   const char *vendor;
3159   %{
3160     SWIGINTERN void XSolvable_vendor_set(XSolvable *xs, const char *vendor) {
3161       Pool *pool = xs->pool;
3162       pool->solvables[xs->id].vendor = pool_str2id(pool, vendor, 1);
3163     }
3164     SWIGINTERN const char *XSolvable_vendor_get(XSolvable *xs) {
3165       Pool *pool = xs->pool;
3166       return pool_id2str(pool, pool->solvables[xs->id].vendor);
3167     }
3168   %}
3169   Id vendorid;
3170   %{
3171     SWIGINTERN void XSolvable_vendorid_set(XSolvable *xs, Id vendorid) {
3172       xs->pool->solvables[xs->id].vendor = vendorid;
3173     }
3174     SWIGINTERN Id XSolvable_vendorid_get(XSolvable *xs) {
3175       return xs->pool->solvables[xs->id].vendor;
3176     }
3177   %}
3178   Repo * const repo;
3179   %{
3180     SWIGINTERN Repo *XSolvable_repo_get(XSolvable *xs) {
3181       return xs->pool->solvables[xs->id].repo;
3182     }
3183   %}
3184
3185   /* old interface, please use the generic add_deparray instead */
3186   void add_provides(DepId id, Id marker = -1) {
3187     Solvable *s = $self->pool->solvables + $self->id;
3188     marker = solv_depmarker(SOLVABLE_PROVIDES, marker);
3189     s->provides = repo_addid_dep(s->repo, s->provides, id, marker);
3190   }
3191   void add_obsoletes(DepId id) {
3192     Solvable *s = $self->pool->solvables + $self->id;
3193     s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, id, 0);
3194   }
3195   void add_conflicts(DepId id) {
3196     Solvable *s = $self->pool->solvables + $self->id;
3197     s->conflicts = repo_addid_dep(s->repo, s->conflicts, id, 0);
3198   }
3199   void add_requires(DepId id, Id marker = -1) {
3200     Solvable *s = $self->pool->solvables + $self->id;
3201     marker = solv_depmarker(SOLVABLE_REQUIRES, marker);
3202     s->requires = repo_addid_dep(s->repo, s->requires, id, marker);
3203   }
3204   void add_recommends(DepId id) {
3205     Solvable *s = $self->pool->solvables + $self->id;
3206     s->recommends = repo_addid_dep(s->repo, s->recommends, id, 0);
3207   }
3208   void add_suggests(DepId id) {
3209     Solvable *s = $self->pool->solvables + $self->id;
3210     s->suggests = repo_addid_dep(s->repo, s->suggests, id, 0);
3211   }
3212   void add_supplements(DepId id) {
3213     Solvable *s = $self->pool->solvables + $self->id;
3214     s->supplements = repo_addid_dep(s->repo, s->supplements, id, 0);
3215   }
3216   void add_enhances(DepId id) {
3217     Solvable *s = $self->pool->solvables + $self->id;
3218     s->enhances = repo_addid_dep(s->repo, s->enhances, id, 0);
3219   }
3220
3221   void unset(Id keyname) {
3222     Solvable *s = $self->pool->solvables + $self->id;
3223     repo_unset(s->repo, $self->id, keyname);
3224   }
3225
3226   void add_deparray(Id keyname, DepId id, Id marker = -1) {
3227     Solvable *s = $self->pool->solvables + $self->id;
3228     solvable_add_deparray(s, keyname, id, marker);
3229   }
3230
3231   %newobject Selection;
3232   Selection *Selection(int setflags=0) {
3233     Selection *sel = new_Selection($self->pool);
3234     queue_push2(&sel->q, SOLVER_SOLVABLE | setflags, $self->id);
3235     return sel;
3236   }
3237
3238 #ifdef SWIGRUBY
3239   %rename("identical?") identical;
3240 #endif
3241   bool identical(XSolvable *s2) {
3242     return solvable_identical($self->pool->solvables + $self->id, s2->pool->solvables + s2->id);
3243   }
3244   int evrcmp(XSolvable *s2) {
3245     return pool_evrcmp($self->pool, $self->pool->solvables[$self->id].evr, s2->pool->solvables[s2->id].evr, EVRCMP_COMPARE);
3246   }
3247 #ifdef SWIGRUBY
3248   %rename("matchesdep?") matchesdep;
3249 #endif
3250   bool matchesdep(Id keyname, DepId id, Id marker = -1) {
3251     return solvable_matchesdep($self->pool->solvables + $self->id, keyname, id, marker);
3252   }
3253
3254 #if defined(SWIGTCL)
3255   %rename("==") __eq__;
3256 #endif
3257   bool __eq__(XSolvable *s) {
3258     return $self->pool == s->pool && $self->id == s->id;
3259   }
3260 #if defined(SWIGTCL)
3261   %rename("!=") __ne__;
3262 #endif
3263   bool __ne__(XSolvable *s) {
3264     return !XSolvable___eq__($self, s);
3265   }
3266 #if defined(SWIGPYTHON)
3267   int __hash__() {
3268     return $self->id;
3269   }
3270 #endif
3271 #if defined(SWIGPERL) || defined(SWIGTCL)
3272   %rename("str") __str__;
3273 #endif
3274   const char *__str__() {
3275     return pool_solvid2str($self->pool, $self->id);
3276   }
3277 #if defined(SWIGPERL) || defined(SWIGTCL)
3278   %rename("repr") __repr__;
3279 #endif
3280   %newobject __repr__;
3281   const char *__repr__() {
3282     char buf[20];
3283     sprintf(buf, "<Solvable #%d ", $self->id);
3284     return solv_dupjoin(buf, pool_solvid2str($self->pool, $self->id), ">");
3285   }
3286 }
3287
3288 %extend Problem {
3289   Problem(Solver *solv, Id id) {
3290     Problem *p;
3291     p = solv_calloc(1, sizeof(*p));
3292     p->solv = solv;
3293     p->id = id;
3294     return p;
3295   }
3296   %newobject findproblemrule;
3297   XRule *findproblemrule() {
3298     Id r = solver_findproblemrule($self->solv, $self->id);
3299     return new_XRule($self->solv, r);
3300   }
3301   %newobject findallproblemrules;
3302   %typemap(out) Queue findallproblemrules Queue2Array(XRule *, 1, new_XRule(arg1->solv, id));
3303   Queue findallproblemrules(int unfiltered=0) {
3304     Solver *solv = $self->solv;
3305     Id probr;
3306     int i, j;
3307     Queue q;
3308     queue_init(&q);
3309     solver_findallproblemrules(solv, $self->id, &q);
3310     if (!unfiltered)
3311       {
3312         for (i = j = 0; i < q.count; i++)
3313           {
3314             SolverRuleinfo rclass;
3315             probr = q.elements[i];
3316             rclass = solver_ruleclass(solv, probr);
3317             if (rclass == SOLVER_RULE_UPDATE || rclass == SOLVER_RULE_JOB)
3318               continue;
3319             q.elements[j++] = probr;
3320           }
3321         if (j)
3322           queue_truncate(&q, j);
3323       }
3324     return q;
3325   }
3326   int solution_count() {
3327     return solver_solution_count($self->solv, $self->id);
3328   }
3329   %typemap(out) Queue solutions Queue2Array(Solution *, 1, new_Solution(arg1, id));
3330   %newobject solutions;
3331   Queue solutions() {
3332     Queue q;
3333     int i, cnt;
3334     queue_init(&q);
3335     cnt = solver_solution_count($self->solv, $self->id);
3336     for (i = 1; i <= cnt; i++)
3337       queue_push(&q, i);
3338     return q;
3339   }
3340 #if defined(SWIGPERL) || defined(SWIGTCL)
3341   %rename("str") __str__;
3342 #endif
3343   const char *__str__() {
3344     return solver_problem2str($self->solv, $self->id);
3345   }
3346 }
3347
3348 %extend Solution {
3349   Solution(Problem *p, Id id) {
3350     Solution *s;
3351     s = solv_calloc(1, sizeof(*s));
3352     s->solv = p->solv;
3353     s->problemid = p->id;
3354     s->id = id;
3355     return s;
3356   }
3357   int element_count() {
3358     return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
3359   }
3360
3361   %typemap(out) Queue elements Queue2Array(Solutionelement *, 4, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2], idp[3]));
3362   %newobject elements;
3363   Queue elements(bool expandreplaces=0) {
3364     Queue q;
3365     int i, cnt;
3366     queue_init(&q);
3367     cnt = solver_solutionelement_count($self->solv, $self->problemid, $self->id);
3368     for (i = 1; i <= cnt; i++)
3369       {
3370         Id p, rp, type;
3371         solver_next_solutionelement($self->solv, $self->problemid, $self->id, i - 1, &p, &rp);
3372         if (p > 0) {
3373           type = rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE;
3374         } else {
3375           type = p;
3376           p = rp;
3377           rp = 0;
3378         }
3379         if (type == SOLVER_SOLUTION_REPLACE && expandreplaces) {
3380           int illegal = policy_is_illegal(self->solv, self->solv->pool->solvables + p, self->solv->pool->solvables + rp, 0);
3381           if (illegal) {
3382             if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) {
3383               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
3384               queue_push2(&q, p, rp);
3385             }
3386             if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) {
3387               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
3388               queue_push2(&q, p, rp);
3389             }
3390             if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) {
3391               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
3392               queue_push2(&q, p, rp);
3393             }
3394             if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0) {
3395               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_NAMECHANGE);
3396               queue_push2(&q, p, rp);
3397             }
3398             continue;
3399           }
3400         }
3401         queue_push2(&q, i, type);
3402         queue_push2(&q, p, rp);
3403       }
3404     return q;
3405   }
3406 }
3407
3408 %extend Solutionelement {
3409   Solutionelement(Solver *solv, Id problemid, Id solutionid, Id id, Id type, Id p, Id rp) {
3410     Solutionelement *e;
3411     e = solv_calloc(1, sizeof(*e));
3412     e->solv = solv;
3413     e->problemid = problemid;
3414     e->solutionid = solutionid;
3415     e->id = id;
3416     e->type = type;
3417     e->p = p;
3418     e->rp = rp;
3419     return e;
3420   }
3421   const char *str() {
3422     Id p = $self->type;
3423     Id rp = $self->p;
3424     int illegal = 0;
3425     if (p == SOLVER_SOLUTION_ERASE)
3426       {
3427         p = rp;
3428         rp = 0;
3429       }
3430     else if (p == SOLVER_SOLUTION_REPLACE)
3431       {
3432         p = rp;
3433         rp = $self->rp;
3434       }
3435     else if (p == SOLVER_SOLUTION_REPLACE_DOWNGRADE)
3436       illegal = POLICY_ILLEGAL_DOWNGRADE;
3437     else if (p == SOLVER_SOLUTION_REPLACE_ARCHCHANGE)
3438       illegal = POLICY_ILLEGAL_ARCHCHANGE;
3439     else if (p == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
3440       illegal = POLICY_ILLEGAL_VENDORCHANGE;
3441     else if (p == SOLVER_SOLUTION_REPLACE_NAMECHANGE)
3442       illegal = POLICY_ILLEGAL_NAMECHANGE;
3443     if (illegal)
3444       return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, illegal, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
3445     return solver_solutionelement2str($self->solv, p, rp);
3446   }
3447   %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, arg1->id, id, arg1->p, arg1->rp));
3448   %newobject replaceelements;
3449   Queue replaceelements() {
3450     Queue q;
3451     int illegal;
3452
3453     queue_init(&q);
3454     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
3455       illegal = 0;
3456     else
3457       illegal = policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
3458     if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
3459       queue_push(&q, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
3460     if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
3461       queue_push(&q, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
3462     if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
3463       queue_push(&q, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
3464     if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0)
3465       queue_push(&q, SOLVER_SOLUTION_REPLACE_NAMECHANGE);
3466     if (!q.count)
3467       queue_push(&q, $self->type);
3468     return q;
3469   }
3470   int illegalreplace() {
3471     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
3472       return 0;
3473     return policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
3474   }
3475   %newobject solvable;
3476   XSolvable * const solvable;
3477   %newobject replacement;
3478   XSolvable * const replacement;
3479   int const jobidx;
3480   %{
3481     SWIGINTERN XSolvable *Solutionelement_solvable_get(Solutionelement *e) {
3482       return new_XSolvable(e->solv->pool, e->p);
3483     }
3484     SWIGINTERN XSolvable *Solutionelement_replacement_get(Solutionelement *e) {
3485       return new_XSolvable(e->solv->pool, e->rp);
3486     }
3487     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
3488       if (e->type != SOLVER_SOLUTION_JOB && e->type != SOLVER_SOLUTION_POOLJOB)
3489         return -1;
3490       return (e->p - 1) / 2;
3491     }
3492   %}
3493   %newobject Job;
3494   Job *Job() {
3495     Id extraflags = solver_solutionelement_extrajobflags($self->solv, $self->problemid, $self->solutionid);
3496     if ($self->type == SOLVER_SOLUTION_JOB || $self->type == SOLVER_SOLUTION_POOLJOB)
3497       return new_Job($self->solv->pool, SOLVER_NOOP, 0);
3498     if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE || $self->type == SOLVER_SOLUTION_BEST)
3499       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_NOTBYUSER|extraflags, $self->p);
3500     if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_NAMECHANGE)
3501       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_NOTBYUSER|extraflags, $self->rp);
3502     if ($self->type == SOLVER_SOLUTION_ERASE)
3503       return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE|extraflags, $self->p);
3504     return 0;
3505   }
3506 }
3507
3508 %extend Solver {
3509   static const int SOLVER_RULE_UNKNOWN = SOLVER_RULE_UNKNOWN;
3510   static const int SOLVER_RULE_PKG = SOLVER_RULE_PKG;
3511   static const int SOLVER_RULE_PKG_NOT_INSTALLABLE = SOLVER_RULE_PKG_NOT_INSTALLABLE;
3512   static const int SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP = SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP;
3513   static const int SOLVER_RULE_PKG_REQUIRES = SOLVER_RULE_PKG_REQUIRES;
3514   static const int SOLVER_RULE_PKG_SELF_CONFLICT = SOLVER_RULE_PKG_SELF_CONFLICT;
3515   static const int SOLVER_RULE_PKG_CONFLICTS = SOLVER_RULE_PKG_CONFLICTS;
3516   static const int SOLVER_RULE_PKG_SAME_NAME = SOLVER_RULE_PKG_SAME_NAME;
3517   static const int SOLVER_RULE_PKG_OBSOLETES = SOLVER_RULE_PKG_OBSOLETES;
3518   static const int SOLVER_RULE_PKG_IMPLICIT_OBSOLETES = SOLVER_RULE_PKG_IMPLICIT_OBSOLETES;
3519   static const int SOLVER_RULE_PKG_INSTALLED_OBSOLETES = SOLVER_RULE_PKG_INSTALLED_OBSOLETES;
3520   static const int SOLVER_RULE_UPDATE = SOLVER_RULE_UPDATE;
3521   static const int SOLVER_RULE_FEATURE = SOLVER_RULE_FEATURE;
3522   static const int SOLVER_RULE_JOB = SOLVER_RULE_JOB;
3523   static const int SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP = SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP;
3524   static const int SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM = SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM;
3525   static const int SOLVER_RULE_JOB_UNKNOWN_PACKAGE = SOLVER_RULE_JOB_UNKNOWN_PACKAGE;
3526   static const int SOLVER_RULE_JOB_UNSUPPORTED = SOLVER_RULE_JOB_UNSUPPORTED;
3527   static const int SOLVER_RULE_DISTUPGRADE = SOLVER_RULE_DISTUPGRADE;
3528   static const int SOLVER_RULE_INFARCH = SOLVER_RULE_INFARCH;
3529   static const int SOLVER_RULE_CHOICE = SOLVER_RULE_CHOICE;
3530   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
3531
3532   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
3533   static const int SOLVER_SOLUTION_POOLJOB = SOLVER_SOLUTION_POOLJOB;
3534   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
3535   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
3536   static const int SOLVER_SOLUTION_BEST = SOLVER_SOLUTION_BEST;
3537   static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE;
3538   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
3539   static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE;
3540   static const int SOLVER_SOLUTION_REPLACE_ARCHCHANGE = SOLVER_SOLUTION_REPLACE_ARCHCHANGE;
3541   static const int SOLVER_SOLUTION_REPLACE_VENDORCHANGE = SOLVER_SOLUTION_REPLACE_VENDORCHANGE;
3542   static const int SOLVER_SOLUTION_REPLACE_NAMECHANGE = SOLVER_SOLUTION_REPLACE_NAMECHANGE;
3543
3544   static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE;
3545   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
3546   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
3547   static const int POLICY_ILLEGAL_NAMECHANGE = POLICY_ILLEGAL_NAMECHANGE;
3548
3549   static const int SOLVER_FLAG_ALLOW_DOWNGRADE = SOLVER_FLAG_ALLOW_DOWNGRADE;
3550   static const int SOLVER_FLAG_ALLOW_ARCHCHANGE = SOLVER_FLAG_ALLOW_ARCHCHANGE;
3551   static const int SOLVER_FLAG_ALLOW_VENDORCHANGE = SOLVER_FLAG_ALLOW_VENDORCHANGE;
3552   static const int SOLVER_FLAG_ALLOW_NAMECHANGE = SOLVER_FLAG_ALLOW_NAMECHANGE;
3553   static const int SOLVER_FLAG_ALLOW_UNINSTALL = SOLVER_FLAG_ALLOW_UNINSTALL;
3554   static const int SOLVER_FLAG_NO_UPDATEPROVIDE = SOLVER_FLAG_NO_UPDATEPROVIDE;
3555   static const int SOLVER_FLAG_SPLITPROVIDES = SOLVER_FLAG_SPLITPROVIDES;
3556   static const int SOLVER_FLAG_IGNORE_RECOMMENDED = SOLVER_FLAG_IGNORE_RECOMMENDED;
3557   static const int SOLVER_FLAG_ADD_ALREADY_RECOMMENDED = SOLVER_FLAG_ADD_ALREADY_RECOMMENDED;
3558   static const int SOLVER_FLAG_NO_INFARCHCHECK = SOLVER_FLAG_NO_INFARCHCHECK;
3559   static const int SOLVER_FLAG_BEST_OBEY_POLICY = SOLVER_FLAG_BEST_OBEY_POLICY;
3560   static const int SOLVER_FLAG_NO_AUTOTARGET = SOLVER_FLAG_NO_AUTOTARGET;
3561   static const int SOLVER_FLAG_DUP_ALLOW_DOWNGRADE = SOLVER_FLAG_DUP_ALLOW_DOWNGRADE;
3562   static const int SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE = SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE;
3563   static const int SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE = SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE;
3564   static const int SOLVER_FLAG_DUP_ALLOW_NAMECHANGE = SOLVER_FLAG_DUP_ALLOW_NAMECHANGE;
3565   static const int SOLVER_FLAG_KEEP_ORPHANS = SOLVER_FLAG_KEEP_ORPHANS;
3566   static const int SOLVER_FLAG_BREAK_ORPHANS = SOLVER_FLAG_BREAK_ORPHANS;
3567   static const int SOLVER_FLAG_FOCUS_INSTALLED = SOLVER_FLAG_FOCUS_INSTALLED;
3568   static const int SOLVER_FLAG_YUM_OBSOLETES = SOLVER_FLAG_YUM_OBSOLETES;
3569   static const int SOLVER_FLAG_NEED_UPDATEPROVIDE = SOLVER_FLAG_NEED_UPDATEPROVIDE;
3570   static const int SOLVER_FLAG_FOCUS_BEST = SOLVER_FLAG_FOCUS_BEST;
3571   static const int SOLVER_FLAG_STRONG_RECOMMENDS = SOLVER_FLAG_STRONG_RECOMMENDS;
3572   static const int SOLVER_FLAG_INSTALL_ALSO_UPDATES = SOLVER_FLAG_INSTALL_ALSO_UPDATES;
3573   static const int SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED = SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED;
3574   static const int SOLVER_FLAG_STRICT_REPO_PRIORITY = SOLVER_FLAG_STRICT_REPO_PRIORITY;
3575
3576   static const int SOLVER_REASON_UNRELATED = SOLVER_REASON_UNRELATED;
3577   static const int SOLVER_REASON_UNIT_RULE = SOLVER_REASON_UNIT_RULE;
3578   static const int SOLVER_REASON_KEEP_INSTALLED = SOLVER_REASON_KEEP_INSTALLED;
3579   static const int SOLVER_REASON_RESOLVE_JOB = SOLVER_REASON_RESOLVE_JOB;
3580   static const int SOLVER_REASON_UPDATE_INSTALLED = SOLVER_REASON_UPDATE_INSTALLED;
3581   static const int SOLVER_REASON_CLEANDEPS_ERASE = SOLVER_REASON_CLEANDEPS_ERASE;
3582   static const int SOLVER_REASON_RESOLVE = SOLVER_REASON_RESOLVE;
3583   static const int SOLVER_REASON_WEAKDEP = SOLVER_REASON_WEAKDEP;
3584   static const int SOLVER_REASON_RESOLVE_ORPHAN = SOLVER_REASON_RESOLVE_ORPHAN;
3585   static const int SOLVER_REASON_RECOMMENDED = SOLVER_REASON_RECOMMENDED;
3586   static const int SOLVER_REASON_SUPPLEMENTED = SOLVER_REASON_SUPPLEMENTED;
3587
3588   /* legacy */
3589   static const int SOLVER_RULE_RPM = SOLVER_RULE_RPM;
3590
3591   ~Solver() {
3592     solver_free($self);
3593   }
3594
3595   int set_flag(int flag, int value) {
3596     return solver_set_flag($self, flag, value);
3597   }
3598   int get_flag(int flag) {
3599     return solver_get_flag($self, flag);
3600   }
3601
3602   %typemap(out) Queue solve Queue2Array(Problem *, 1, new_Problem(arg1, id));
3603   %newobject solve;
3604   Queue solve(Queue solvejobs) {
3605     Queue q;
3606     int i, cnt;
3607     queue_init(&q);
3608     solver_solve($self, &solvejobs);
3609     cnt = solver_problem_count($self);
3610     for (i = 1; i <= cnt; i++)
3611       queue_push(&q, i);
3612     return q;
3613   }
3614
3615   %newobject transaction;
3616   Transaction *transaction() {
3617     return solver_create_transaction($self);
3618   }
3619
3620   int describe_decision(XSolvable *s, XRule **OUTPUT) {
3621     int ruleid;
3622     int reason = solver_describe_decision($self, s->id, &ruleid);
3623     *OUTPUT = new_XRule($self, ruleid);
3624     return reason;
3625   }
3626
3627   %newobject describe_weakdep_decision_raw;
3628   Queue describe_weakdep_decision_raw(XSolvable *s) {
3629     Queue q;
3630     queue_init(&q);
3631     solver_describe_weakdep_decision($self, s->id, &q);
3632     return q;
3633   }
3634 #if defined(SWIGPYTHON)
3635   %pythoncode {
3636     def describe_weakdep_decision(self, s):
3637       d = iter(self.describe_weakdep_decision_raw(s))
3638       return [ (t, XSolvable(self.pool, sid), Dep(self.pool, id)) for t, sid, id in zip(d, d, d) ]
3639   }
3640 #endif
3641 #if defined(SWIGPERL)
3642   %perlcode {
3643     sub solv::Solver::describe_weakdep_decision {
3644       my ($self, $s) = @_;
3645       my $pool = $self->{'pool'};
3646       my @res;
3647       my @d = $self->describe_weakdep_decision_raw($s);
3648       push @res, [ splice(@d, 0, 3) ] while @d;
3649       return map { [ $_->[0], solv::XSolvable->new($pool, $_->[1]), solv::Dep->new($pool, $_->[2]) ] } @res;
3650     }
3651   }
3652 #endif
3653 #if defined(SWIGRUBY)
3654 %init %{
3655 rb_eval_string(
3656     "class Solv::Solver\n"
3657     "  def describe_weakdep_decision(s)\n"
3658     "    self.describe_weakdep_decision_raw(s).each_slice(3).map { |t, sid, id| [ t, Solv::XSolvable.new(self.pool, sid), Solv::Dep.new(self.pool, id)] }\n"
3659     "  end\n"
3660     "end\n"
3661   );
3662 %}
3663 #endif
3664
3665   int alternatives_count() {
3666     return solver_alternatives_count($self);
3667   }
3668
3669   %newobject alternative;
3670   Alternative *alternative(Id aid) {
3671     Alternative *a = solv_calloc(1, sizeof(*a));
3672     a->solv = $self;
3673     queue_init(&a->choices);
3674     a->type = solver_get_alternative($self, aid, &a->dep_id, &a->from_id, &a->chosen_id, &a->choices, &a->level);
3675     if (!a->type) {
3676       queue_free(&a->choices);
3677       solv_free(a);
3678       return 0;
3679     }
3680     if (a->type == SOLVER_ALTERNATIVE_TYPE_RULE) {
3681       a->rid = a->dep_id;
3682       a->dep_id = 0;
3683     }
3684     return a;
3685   }
3686
3687   %typemap(out) Queue all_alternatives Queue2Array(Alternative *, 1, Solver_alternative(arg1, id));
3688   %newobject all_alternatives;
3689   Queue all_alternatives() {
3690     Queue q;
3691     int i, cnt;
3692     queue_init(&q);
3693     cnt = solver_alternatives_count($self);
3694     for (i = 1; i <= cnt; i++)
3695       queue_push(&q, i);
3696     return q;
3697   }
3698
3699   bool write_testcase(const char *dir) {
3700     return testcase_write($self, dir, TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS, 0, 0);
3701   }
3702
3703   Queue raw_decisions(int filter=0) {
3704     Queue q;
3705     queue_init(&q);
3706     solver_get_decisionqueue($self, &q);
3707     if (filter) {
3708       int i, j;
3709       for (i = j = 0; i < q.count; i++)
3710         if ((filter > 0 && q.elements[i] > 1) ||
3711             (filter < 0 && q.elements[i] < 0))
3712           q.elements[j++] = q.elements[i];
3713       queue_truncate(&q, j);
3714     }
3715     return q;
3716   }
3717
3718   %typemap(out) Queue get_recommended Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3719   %newobject get_recommended;
3720   Queue get_recommended(bool noselected=0) {
3721     Queue q;
3722     queue_init(&q);
3723     solver_get_recommendations($self, &q, NULL, noselected);
3724     return q;
3725   }
3726   %typemap(out) Queue get_suggested Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3727   %newobject get_suggested;
3728   Queue get_suggested(bool noselected=0) {
3729     Queue q;
3730     queue_init(&q);
3731     solver_get_recommendations($self, NULL, &q, noselected);
3732     return q;
3733   }
3734 }
3735
3736 %extend Transaction {
3737   static const int SOLVER_TRANSACTION_IGNORE = SOLVER_TRANSACTION_IGNORE;
3738   static const int SOLVER_TRANSACTION_ERASE = SOLVER_TRANSACTION_ERASE;
3739   static const int SOLVER_TRANSACTION_REINSTALLED = SOLVER_TRANSACTION_REINSTALLED;
3740   static const int SOLVER_TRANSACTION_DOWNGRADED = SOLVER_TRANSACTION_DOWNGRADED;
3741   static const int SOLVER_TRANSACTION_CHANGED = SOLVER_TRANSACTION_CHANGED;
3742   static const int SOLVER_TRANSACTION_UPGRADED = SOLVER_TRANSACTION_UPGRADED;
3743   static const int SOLVER_TRANSACTION_OBSOLETED = SOLVER_TRANSACTION_OBSOLETED;
3744   static const int SOLVER_TRANSACTION_INSTALL = SOLVER_TRANSACTION_INSTALL;
3745   static const int SOLVER_TRANSACTION_REINSTALL = SOLVER_TRANSACTION_REINSTALL;
3746   static const int SOLVER_TRANSACTION_DOWNGRADE = SOLVER_TRANSACTION_DOWNGRADE;
3747   static const int SOLVER_TRANSACTION_CHANGE = SOLVER_TRANSACTION_CHANGE;
3748   static const int SOLVER_TRANSACTION_UPGRADE = SOLVER_TRANSACTION_UPGRADE;
3749   static const int SOLVER_TRANSACTION_OBSOLETES = SOLVER_TRANSACTION_OBSOLETES;
3750   static const int SOLVER_TRANSACTION_MULTIINSTALL = SOLVER_TRANSACTION_MULTIINSTALL;
3751   static const int SOLVER_TRANSACTION_MULTIREINSTALL = SOLVER_TRANSACTION_MULTIREINSTALL;
3752   static const int SOLVER_TRANSACTION_MAXTYPE = SOLVER_TRANSACTION_MAXTYPE;
3753   static const int SOLVER_TRANSACTION_SHOW_ACTIVE = SOLVER_TRANSACTION_SHOW_ACTIVE;
3754   static const int SOLVER_TRANSACTION_SHOW_ALL = SOLVER_TRANSACTION_SHOW_ALL;
3755   static const int SOLVER_TRANSACTION_SHOW_OBSOLETES = SOLVER_TRANSACTION_SHOW_OBSOLETES;
3756   static const int SOLVER_TRANSACTION_SHOW_MULTIINSTALL = SOLVER_TRANSACTION_SHOW_MULTIINSTALL;
3757   static const int SOLVER_TRANSACTION_CHANGE_IS_REINSTALL = SOLVER_TRANSACTION_CHANGE_IS_REINSTALL;
3758   static const int SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE = SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE;
3759   static const int SOLVER_TRANSACTION_MERGE_VENDORCHANGES = SOLVER_TRANSACTION_MERGE_VENDORCHANGES;
3760   static const int SOLVER_TRANSACTION_MERGE_ARCHCHANGES = SOLVER_TRANSACTION_MERGE_ARCHCHANGES;
3761   static const int SOLVER_TRANSACTION_RPM_ONLY = SOLVER_TRANSACTION_RPM_ONLY;
3762   static const int SOLVER_TRANSACTION_ARCHCHANGE = SOLVER_TRANSACTION_ARCHCHANGE;
3763   static const int SOLVER_TRANSACTION_VENDORCHANGE = SOLVER_TRANSACTION_VENDORCHANGE;
3764   static const int SOLVER_TRANSACTION_KEEP_ORDERDATA = SOLVER_TRANSACTION_KEEP_ORDERDATA;
3765   ~Transaction() {
3766     transaction_free($self);
3767   }
3768 #ifdef SWIGRUBY
3769   %rename("isempty?") isempty;
3770 #endif
3771   bool isempty() {
3772     return $self->steps.count == 0;
3773   }
3774
3775   %newobject othersolvable;
3776   XSolvable *othersolvable(XSolvable *s) {
3777     Id op = transaction_obs_pkg($self, s->id);
3778     return new_XSolvable($self->pool, op);
3779   }
3780
3781   %typemap(out) Queue allothersolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3782   %newobject allothersolvables;
3783   Queue allothersolvables(XSolvable *s) {
3784     Queue q;
3785     queue_init(&q);
3786     transaction_all_obs_pkgs($self, s->id, &q);
3787     return q;
3788   }
3789
3790   %typemap(out) Queue classify Queue2Array(TransactionClass *, 4, new_TransactionClass(arg1, arg2, id, idp[1], idp[2], idp[3]));
3791   %newobject classify;
3792   Queue classify(int mode = 0) {
3793     Queue q;
3794     queue_init(&q);
3795     transaction_classify($self, mode, &q);
3796     return q;
3797   }
3798
3799   /* deprecated, use newsolvables instead */
3800   %typemap(out) Queue newpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3801   %newobject newpackages;
3802   Queue newpackages() {
3803     Queue q;
3804     int cut;
3805     queue_init(&q);
3806     cut = transaction_installedresult(self, &q);
3807     queue_truncate(&q, cut);
3808     return q;
3809   }
3810
3811   /* deprecated, use keptsolvables instead */
3812   %typemap(out) Queue keptpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3813   %newobject keptpackages;
3814   Queue keptpackages() {
3815     Queue q;
3816     int cut;
3817     queue_init(&q);
3818     cut = transaction_installedresult(self, &q);
3819     if (cut)
3820       queue_deleten(&q, 0, cut);
3821     return q;
3822   }
3823
3824   %typemap(out) Queue newsolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3825   %newobject newsolvables;
3826   Queue newsolvables() {
3827     Queue q;
3828     int cut;
3829     queue_init(&q);
3830     cut = transaction_installedresult(self, &q);
3831     queue_truncate(&q, cut);
3832     return q;
3833   }
3834
3835   %typemap(out) Queue keptsolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3836   %newobject keptsolvables;
3837   Queue keptsolvables() {
3838     Queue q;
3839     int cut;
3840     queue_init(&q);
3841     cut = transaction_installedresult(self, &q);
3842     if (cut)
3843       queue_deleten(&q, 0, cut);
3844     return q;
3845   }
3846
3847   %typemap(out) Queue steps Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
3848   %newobject steps;
3849   Queue steps() {
3850     Queue q;
3851     queue_init_clone(&q, &$self->steps);
3852     return q;
3853   }
3854
3855   int steptype(XSolvable *s, int mode) {
3856     return transaction_type($self, s->id, mode);
3857   }
3858   long long calc_installsizechange() {
3859     return transaction_calc_installsizechange($self);
3860   }
3861   void order(int flags=0) {
3862     transaction_order($self, flags);
3863   }
3864 }
3865
3866 %extend TransactionClass {
3867   TransactionClass(Transaction *trans, int mode, Id type, int count, Id fromid, Id toid) {
3868     TransactionClass *cl = solv_calloc(1, sizeof(*cl));
3869     cl->transaction = trans;
3870     cl->mode = mode;
3871     cl->type = type;
3872     cl->count = count;
3873     cl->fromid = fromid;
3874     cl->toid = toid;
3875     return cl;
3876   }
3877   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->transaction->pool, id));
3878   %newobject solvables;
3879   Queue solvables() {
3880     Queue q;
3881     queue_init(&q);
3882     transaction_classify_pkgs($self->transaction, $self->mode, $self->type, $self->fromid, $self->toid, &q);
3883     return q;
3884   }
3885   const char * const fromstr;
3886   const char * const tostr;
3887   %{
3888     SWIGINTERN const char *TransactionClass_fromstr_get(TransactionClass *cl) {
3889       return pool_id2str(cl->transaction->pool, cl->fromid);
3890     }
3891     SWIGINTERN const char *TransactionClass_tostr_get(TransactionClass *cl) {
3892       return pool_id2str(cl->transaction->pool, cl->toid);
3893     }
3894   %}
3895 }
3896
3897 %extend XRule {
3898   XRule(Solver *solv, Id id) {
3899     if (!id)
3900       return 0;
3901     XRule *xr = solv_calloc(1, sizeof(*xr));
3902     xr->solv = solv;
3903     xr->id = id;
3904     return xr;
3905   }
3906   int const type;
3907   %{
3908     SWIGINTERN int XRule_type_get(XRule *xr) {
3909       return solver_ruleclass(xr->solv, xr->id);
3910     }
3911   %}
3912   %newobject info;
3913   Ruleinfo *info() {
3914     Id type, source, target, dep;
3915     type = solver_ruleinfo($self->solv, $self->id, &source, &target, &dep);
3916     return new_Ruleinfo($self, type, source, target, dep);
3917   }
3918   %typemap(out) Queue allinfos Queue2Array(Ruleinfo *, 4, new_Ruleinfo(arg1, id, idp[1], idp[2], idp[3]));
3919   %newobject allinfos;
3920   Queue allinfos() {
3921     Queue q;
3922     queue_init(&q);
3923     solver_allruleinfos($self->solv, $self->id, &q);
3924     return q;
3925   }
3926
3927 #if defined(SWIGTCL)
3928   %rename("==") __eq__;
3929 #endif
3930   bool __eq__(XRule *xr) {
3931     return $self->solv == xr->solv && $self->id == xr->id;
3932   }
3933 #if defined(SWIGTCL)
3934   %rename("!=") __ne__;
3935 #endif
3936   bool __ne__(XRule *xr) {
3937     return !XRule___eq__($self, xr);
3938   }
3939 #if defined(SWIGPYTHON)
3940   int __hash__() {
3941     return $self->id;
3942   }
3943 #endif
3944 #if defined(SWIGPERL) || defined(SWIGTCL)
3945   %rename("repr") __repr__;
3946 #endif
3947   %newobject __repr__;
3948   const char *__repr__() {
3949     char buf[20];
3950     sprintf(buf, "<Rule #%d>", $self->id);
3951     return solv_strdup(buf);
3952   }
3953 }
3954
3955 %extend Ruleinfo {
3956   Ruleinfo(XRule *r, Id type, Id source, Id target, Id dep_id) {
3957     Ruleinfo *ri = solv_calloc(1, sizeof(*ri));
3958     ri->solv = r->solv;
3959     ri->rid = r->id;
3960     ri->type = type;
3961     ri->source = source;
3962     ri->target = target;
3963     ri->dep_id = dep_id;
3964     return ri;
3965   }
3966   %newobject solvable;
3967   XSolvable * const solvable;
3968   %newobject othersolvable;
3969   XSolvable * const othersolvable;
3970   %newobject dep;
3971   Dep * const dep;
3972   %{
3973     SWIGINTERN XSolvable *Ruleinfo_solvable_get(Ruleinfo *ri) {
3974       return new_XSolvable(ri->solv->pool, ri->source);
3975     }
3976     SWIGINTERN XSolvable *Ruleinfo_othersolvable_get(Ruleinfo *ri) {
3977       return new_XSolvable(ri->solv->pool, ri->target);
3978     }
3979     SWIGINTERN Dep *Ruleinfo_dep_get(Ruleinfo *ri) {
3980       return new_Dep(ri->solv->pool, ri->dep_id);
3981     }
3982   %}
3983   const char *problemstr() {
3984     return solver_problemruleinfo2str($self->solv, $self->type, $self->source, $self->target, $self->dep_id);
3985   }
3986 }
3987
3988 %extend XRepodata {
3989   XRepodata(Repo *repo, Id id) {
3990     XRepodata *xr = solv_calloc(1, sizeof(*xr));
3991     xr->repo = repo;
3992     xr->id = id;
3993     return xr;
3994   }
3995   Id new_handle() {
3996     return repodata_new_handle(repo_id2repodata($self->repo, $self->id));
3997   }
3998   void set_id(Id solvid, Id keyname, DepId id) {
3999     repodata_set_id(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
4000   }
4001   void set_num(Id solvid, Id keyname, unsigned long long num) {
4002     repodata_set_num(repo_id2repodata($self->repo, $self->id), solvid, keyname, num);
4003   }
4004   void set_str(Id solvid, Id keyname, const char *str) {
4005     repodata_set_str(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
4006   }
4007   void set_void(Id solvid, Id keyname) {
4008     repodata_set_void(repo_id2repodata($self->repo, $self->id), solvid, keyname);
4009   }
4010   void set_poolstr(Id solvid, Id keyname, const char *str) {
4011     repodata_set_poolstr(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
4012   }
4013   void add_idarray(Id solvid, Id keyname, DepId id) {
4014     repodata_add_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
4015   }
4016   void add_flexarray(Id solvid, Id keyname, Id handle) {
4017     repodata_add_flexarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, handle);
4018   }
4019   void set_checksum(Id solvid, Id keyname, Chksum *chksum) {
4020     const unsigned char *buf = solv_chksum_get(chksum, 0);
4021     if (buf)
4022       repodata_set_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, solv_chksum_get_type(chksum), buf);
4023   }
4024   void set_sourcepkg(Id solvid, const char *sourcepkg) {
4025     repodata_set_sourcepkg(repo_id2repodata($self->repo, $self->id), solvid, sourcepkg);
4026   }
4027   void set_location(Id solvid, unsigned int mediano, const char *location) {
4028     repodata_set_location(repo_id2repodata($self->repo, $self->id), solvid, mediano, 0, location);
4029   }
4030   void unset(Id solvid, Id keyname) {
4031     repodata_unset(repo_id2repodata($self->repo, $self->id), solvid, keyname);
4032   }
4033   const char *lookup_str(Id solvid, Id keyname) {
4034     return repodata_lookup_str(repo_id2repodata($self->repo, $self->id), solvid, keyname);
4035   }
4036   Id lookup_id(Id solvid, Id keyname) {
4037     return repodata_lookup_id(repo_id2repodata($self->repo, $self->id), solvid, keyname);
4038   }
4039   unsigned long long lookup_num(Id solvid, Id keyname, unsigned long long notfound = 0) {
4040     return repodata_lookup_num(repo_id2repodata($self->repo, $self->id), solvid, keyname, notfound);
4041   }
4042   bool lookup_void(Id solvid, Id keyname) {
4043     return repodata_lookup_void(repo_id2repodata($self->repo, $self->id), solvid, keyname);
4044   }
4045   Queue lookup_idarray(Id solvid, Id keyname) {
4046     Queue r;
4047     queue_init(&r);
4048     repodata_lookup_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, &r);
4049     return r;
4050   }
4051   %newobject lookup_checksum;
4052   Chksum *lookup_checksum(Id solvid, Id keyname) {
4053     Id type = 0;
4054     const unsigned char *b = repodata_lookup_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, &type);
4055     return solv_chksum_create_from_bin(type, b);
4056   }
4057   void internalize() {
4058     repodata_internalize(repo_id2repodata($self->repo, $self->id));
4059   }
4060   void create_stubs() {
4061     Repodata *data = repo_id2repodata($self->repo, $self->id);
4062     data = repodata_create_stubs(data);
4063     $self->id = data->repodataid;
4064   }
4065   bool write(FILE *fp) {
4066     return repodata_write(repo_id2repodata($self->repo, $self->id), fp) == 0;
4067   }
4068   Id str2dir(const char *dir, bool create=1) {
4069     Repodata *data = repo_id2repodata($self->repo, $self->id);
4070     return repodata_str2dir(data, dir, create);
4071   }
4072   const char *dir2str(Id did, const char *suf = 0) {
4073     Repodata *data = repo_id2repodata($self->repo, $self->id);
4074     return repodata_dir2str(data, did, suf);
4075   }
4076   void add_dirstr(Id solvid, Id keyname, Id dir, const char *str) {
4077     Repodata *data = repo_id2repodata($self->repo, $self->id);
4078     repodata_add_dirstr(data, solvid, keyname, dir, str);
4079   }
4080   bool add_solv(FILE *fp, int flags = 0) {
4081     Repodata *data = repo_id2repodata($self->repo, $self->id);
4082     int r, oldstate = data->state;
4083     data->state = REPODATA_LOADING;
4084     r = repo_add_solv(data->repo, fp, flags | REPO_USE_LOADING);
4085     if (r || data->state == REPODATA_LOADING)
4086       data->state = oldstate;
4087     return r;
4088   }
4089   void extend_to_repo() {
4090     Repodata *data = repo_id2repodata($self->repo, $self->id);
4091     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
4092   }
4093 #if defined(SWIGTCL)
4094   %rename("==") __eq__;
4095 #endif
4096   bool __eq__(XRepodata *xr) {
4097     return $self->repo == xr->repo && $self->id == xr->id;
4098   }
4099 #if defined(SWIGTCL)
4100   %rename("!=") __ne__;
4101 #endif
4102   bool __ne__(XRepodata *xr) {
4103     return !XRepodata___eq__($self, xr);
4104   }
4105 #if defined(SWIGPYTHON)
4106   int __hash__() {
4107     return $self->id;
4108   }
4109 #endif
4110 #if defined(SWIGPERL) || defined(SWIGTCL)
4111   %rename("repr") __repr__;
4112 #endif
4113   %newobject __repr__;
4114   const char *__repr__() {
4115     char buf[20];
4116     sprintf(buf, "<Repodata #%d>", $self->id);
4117     return solv_strdup(buf);
4118   }
4119 }
4120
4121 #ifdef ENABLE_PUBKEY
4122 %extend Solvsig {
4123   Solvsig(FILE *fp) {
4124     return solvsig_create(fp);
4125   }
4126   ~Solvsig() {
4127     solvsig_free($self);
4128   }
4129   %newobject Chksum;
4130   Chksum *Chksum() {
4131     return $self->htype ? (Chksum *)solv_chksum_create($self->htype) : 0;
4132   }
4133 #ifdef ENABLE_PGPVRFY
4134   %newobject verify;
4135   XSolvable *verify(Repo *repo, Chksum *chksum) {
4136     Id p = solvsig_verify($self, repo, chksum);
4137     return new_XSolvable(repo->pool, p);
4138   }
4139 #endif
4140 }
4141 #endif
4142
4143 %extend Alternative {
4144   static const int SOLVER_ALTERNATIVE_TYPE_RULE = SOLVER_ALTERNATIVE_TYPE_RULE;
4145   static const int SOLVER_ALTERNATIVE_TYPE_RECOMMENDS = SOLVER_ALTERNATIVE_TYPE_RECOMMENDS;
4146   static const int SOLVER_ALTERNATIVE_TYPE_SUGGESTS = SOLVER_ALTERNATIVE_TYPE_SUGGESTS;
4147
4148   ~Alternative() {
4149     queue_free(&$self->choices);
4150     solv_free($self);
4151   }
4152   %newobject chosen;
4153   XSolvable * const chosen;
4154   %newobject rule;
4155   XRule * const rule;
4156   %newobject depsolvable;
4157   XSolvable * const depsolvable;
4158   %newobject dep;
4159   Dep * const dep;
4160   %{
4161     SWIGINTERN XSolvable *Alternative_chosen_get(Alternative *a) {
4162       return new_XSolvable(a->solv->pool, a->chosen_id);
4163     }
4164     SWIGINTERN XRule *Alternative_rule_get(Alternative *a) {
4165       return new_XRule(a->solv, a->rid);
4166     }
4167     SWIGINTERN XSolvable *Alternative_depsolvable_get(Alternative *a) {
4168       return new_XSolvable(a->solv->pool, a->from_id);
4169     }
4170     SWIGINTERN Dep *Alternative_dep_get(Alternative *a) {
4171       return new_Dep(a->solv->pool, a->dep_id);
4172     }
4173   %}
4174
4175   Queue choices_raw() {
4176     Queue r;
4177     queue_init_clone(&r, &$self->choices);
4178     return r;
4179   }
4180
4181   %typemap(out) Queue choices Queue2Array(XSolvable *, 1, new_XSolvable(arg1->solv->pool, id));
4182   Queue choices() {
4183     int i;
4184     Queue r;
4185     queue_init_clone(&r, &$self->choices);
4186     for (i = 0; i < r.count; i++)
4187       if (r.elements[i] < 0)
4188         r.elements[i] = -r.elements[i];
4189     return r;
4190   }
4191
4192 #if defined(SWIGPERL) || defined(SWIGTCL)
4193   %rename("str") __str__;
4194 #endif
4195   const char *__str__() {
4196     return solver_alternative2str($self->solv, $self->type, $self->type == SOLVER_ALTERNATIVE_TYPE_RULE ? $self->rid : $self->dep_id, $self->from_id);
4197   }
4198 }
4199
4200 #if defined(SWIGTCL)
4201 %init %{
4202   Tcl_Eval(interp,
4203 "proc solv::iter {varname iter body} {\n"\
4204 "  while 1 {\n"\
4205 "    set value [$iter __next__]\n"\
4206 "    if {$value eq \"NULL\"} { break }\n"\
4207 "    uplevel [list set $varname $value]\n"\
4208 "    set code [catch {uplevel $body} result]\n"\
4209 "    switch -exact -- $code {\n"\
4210 "      0 {}\n"\
4211 "      3 { return }\n"\
4212 "      4 {}\n"\
4213 "      default { return -code $code $result }\n"\
4214 "    }\n"\
4215 "  }\n"\
4216 "}\n"
4217   );
4218 %}
4219 #endif
4220