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