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