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