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