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