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