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