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