make FILE objects autoclose the fd in the destructor
[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 #
8 ##if defined(SWIGRUBY)
9 #  %rename("to_s") string();
10 ##endif
11 ##if defined(SWIGPYTHON)
12 #  %rename("__str__") string();
13 ##endif
14 #
15
16 %module solv
17
18 #ifdef SWIGRUBY
19 %markfunc Pool "mark_Pool";
20 #endif
21
22 #if defined(SWIGPYTHON)
23 %typemap(in) Queue {
24   /* Check if is a list */
25   queue_init(&$1);
26   if (PyList_Check($input)) {
27     int size = PyList_Size($input);
28     int i = 0;
29     for (i = 0; i < size; i++) {
30       PyObject *o = PyList_GetItem($input,i);
31       int v;
32       int e = SWIG_AsVal_int(o, &v);
33       if (!SWIG_IsOK(e)) {
34         SWIG_exception_fail(SWIG_ArgError(e), "list must contain only integers");
35         queue_free(&$1);
36         return NULL;
37       }
38       queue_push(&$1, v);
39     }
40   } else {
41     PyErr_SetString(PyExc_TypeError,"not a list");
42     return NULL;
43   }
44 }
45
46 %typemap(out) Queue {
47   int i;
48   PyObject *o = PyList_New($1.count);
49   for (i = 0; i < $1.count; i++)
50     PyList_SetItem(o, i, SWIG_From_int($1.elements[i]));
51   queue_free(&$1);
52   $result = o;
53 }
54
55 %define Queue2Array(type, step, con) %{
56   int i;
57   int cnt = $1.count / step;
58   Id *idp = $1.elements;
59   PyObject *o = PyList_New(cnt);
60   for (i = 0; i < cnt; i++, idp += step)
61     {
62       Id id = *idp;
63 #define result resultx
64       type result = con;
65       $typemap(out, type)
66       PyList_SetItem(o, i, $result);
67 #undef result
68     }
69   queue_free(&$1);
70   $result = o;
71 %}
72
73 %enddef
74
75 #endif
76
77
78 #if defined(SWIGPERL)
79 %typemap(in) Queue {
80   AV *av;
81   int i, size;
82   queue_init(&$1);
83   if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV)
84     SWIG_croak("Argument $argnum is not an array reference.");
85   av = (AV*)SvRV($input);
86   size = av_len(av);
87   for (i = 0; i <= size; i++) {
88     SV **sv = av_fetch(av, i, 0);
89     int v;
90     int e = SWIG_AsVal_int(*sv, &v);
91     if (!SWIG_IsOK(e)) {
92       SWIG_croak("list must contain only integers");
93     }
94     queue_push(&$1, v);
95   }
96 }
97 # AV *o = newAV();
98 # av_push(o, SvREFCNT_inc(SWIG_From_int($1.elements[i])));
99 # $result = newRV_noinc((SV*)o); argvi++;
100 #
101 %typemap(out) Queue {
102   int i;
103   if (argvi + $1.count + 1>= items) {
104     EXTEND(sp, items - (argvi + $1.count + 1) + 1);
105   }
106   for (i = 0; i < $1.count; i++)
107     ST(argvi++) = SvREFCNT_inc(SWIG_From_int($1.elements[i]));
108   queue_free(&$1);
109   $result = 0;
110 }
111 %define Queue2Array(type, step, con) %{
112   int i;
113   int cnt = $1.count / step;
114   Id *idp = $1.elements;
115   if (argvi + cnt + 1 >= items) {
116     EXTEND(sp, items - (argvi + cnt + 1) + 1);
117   }
118   for (i = 0; i < cnt; i++, idp += step)
119     {
120       Id id = *idp;
121 #define result resultx
122       type result = con;
123       $typemap(out, type)
124       SvREFCNT_inc(ST(argvi - 1));
125 #undef result
126     }
127   queue_free(&$1);
128   $result = 0;
129 %}
130 %enddef
131
132 #endif
133
134 %typemap(arginit) Queue {
135   queue_init(&$1);
136 }
137 %typemap(freearg) Queue {
138   queue_free(&$1);
139 }
140
141 #if defined(SWIGRUBY)
142 %typemap(in) Queue {
143   int size, i;
144   VALUE *o;
145   queue_init(&$1);
146   size = RARRAY_LEN($input);
147   i = 0;
148   o = RARRAY_PTR($input);
149   for (i = 0; i < size; i++, o++) {
150     int v;
151     int e = SWIG_AsVal_int(*o, &v);
152     if (!SWIG_IsOK(e))
153       {
154         SWIG_Error(SWIG_RuntimeError, "list must contain only integers");
155         SWIG_fail;
156       }
157     queue_push(&$1, v);
158   }
159 }
160 %typemap(out) Queue {
161   int i;
162   VALUE o = rb_ary_new2($1.count);
163   for (i = 0; i < $1.count; i++)
164     rb_ary_store(o, i, SWIG_From_int($1.elements[i]));
165   queue_free(&$1);
166   $result = o;
167 }
168 %typemap(arginit) Queue {
169   queue_init(&$1);
170 }
171 %typemap(freearg) Queue {
172   queue_free(&$1);
173 }
174 %define Queue2Array(type, step, con) %{
175   int i;
176   int cnt = $1.count / step;
177   Id *idp = $1.elements;
178   VALUE o = rb_ary_new2(cnt);
179   for (i = 0; i < cnt; i++, idp += step)
180     {
181       Id id = *idp;
182 #define result resultx
183       type result = con;
184       $typemap(out, type)
185       rb_ary_store(o, i, $result);
186 #undef result
187     }
188   queue_free(&$1);
189   $result = o;
190 %}
191 %enddef
192 #endif
193
194
195
196
197 #if defined(SWIGPERL)
198
199 # work around a swig bug
200 %{
201 #undef SWIG_CALLXS
202 #ifdef PERL_OBJECT 
203 #  define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv,pPerl) 
204 #else 
205 #  ifndef MULTIPLICITY 
206 #    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv) 
207 #  else 
208 #    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(PERL_GET_THX, cv) 
209 #  endif 
210 #endif 
211 %}
212
213
214 %define perliter(class)
215   %perlcode {
216     sub class##::FETCH {
217       my $i = ${##class##::ITERATORS}{$_[0]};
218       if ($i) {
219         $_[1] == $i->[0] - 1 ? $i->[1] : undef;
220       } else {
221         $_[0]->__getitem__($_[1]);
222       }
223     }
224     sub class##::FETCHSIZE {
225       my $i = ${##class##::ITERATORS}{$_[0]};
226       if ($i) {
227         ($i->[1] = $_[0]->__next__()) ? ++$i->[0]  : 0;
228       } else {
229         $_[0]->__len__();
230       }
231     }
232   }
233 %enddef
234
235 %{
236
237 #define SWIG_PERL_ITERATOR      0x80
238
239 SWIGRUNTIMEINLINE SV *
240 SWIG_Perl_NewArrayObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int flags) {
241   SV *result = sv_newmortal();
242   if (ptr && (flags & (SWIG_SHADOW | SWIG_POINTER_OWN))) {
243     SV *self;
244     SV *obj=newSV(0);
245     AV *array=newAV();
246     HV *stash;
247     sv_setref_pv(obj, (char *) SWIG_Perl_TypeProxyName(t), ptr);
248     stash=SvSTASH(SvRV(obj));
249     if (flags & SWIG_POINTER_OWN) {
250       HV *hv;
251       GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE);
252       if (!isGV(gv))
253         gv_init(gv, stash, "OWNER", 5, FALSE);
254       hv=GvHVn(gv);
255       hv_store_ent(hv, obj, newSViv(1), 0);
256     }
257     if (flags & SWIG_PERL_ITERATOR) {
258       HV *hv;
259       GV *gv=*(GV**)hv_fetch(stash, "ITERATORS", 9, TRUE);
260       AV *av=newAV();
261       if (!isGV(gv))
262         gv_init(gv, stash, "ITERATORS", 9, FALSE);
263       hv=GvHVn(gv);
264       hv_store_ent(hv, obj, newRV_inc((SV *)av), 0);
265     }
266     sv_magic((SV *)array, (SV *)obj, 'P', Nullch, 0);
267     SvREFCNT_dec(obj);
268     self=newRV_noinc((SV *)array);
269     sv_setsv(result, self);
270     SvREFCNT_dec((SV *)self);
271     sv_bless(result, stash);
272   } else {
273     sv_setref_pv(result, (char *) SWIG_Perl_TypeProxyName(t), ptr);
274   }
275   return result;
276 }
277
278 %}
279
280 %typemap(out) Perlarray {
281   ST(argvi) = SWIG_Perl_NewArrayObj(SWIG_PERL_OBJECT_CALL SWIG_as_voidptr(result), $1_descriptor, $owner | $shadow); argvi++;
282 }
283 %typemap(out) Perliterator {
284   ST(argvi) = SWIG_Perl_NewArrayObj(SWIG_PERL_OBJECT_CALL SWIG_as_voidptr(result), $1_descriptor, $owner | $shadow | SWIG_PERL_ITERATOR); argvi++;
285 }
286
287 %typemap(out) Pool_solvable_iterator * = Perlarray;
288 %typemap(out) Pool_solvable_iterator * solvables_iter = Perliterator;
289 %typemap(out) Pool_repo_iterator * = Perlarray;
290 %typemap(out) Pool_repo_iterator * repos_iter = Perliterator;
291 %typemap(out) Repo_solvable_iterator * = Perlarray;
292 %typemap(out) Repo_solvable_iterator * solvables_iter = Perliterator;
293 %typemap(out) Dataiterator * = Perliterator;
294
295 #endif
296
297
298
299 #if defined(SWIGPYTHON)
300 typedef PyObject *AppObjectPtr;
301 %typemap(out) AppObjectPtr {
302   $result = $1 ? $1 : Py_None;
303   Py_INCREF($result);
304 }
305 #endif
306 #if defined(SWIGPERL)
307 typedef SV *AppObjectPtr;
308 %typemap(in) AppObjectPtr {
309   $1 = SvROK($input) ? SvRV($input) : 0;
310 }
311 %typemap(out) AppObjectPtr {
312   $result = $1 ? newRV_inc($1) : newSV(0);
313   argvi++;
314 }
315 #endif
316 #if defined(SWIGRUBY)
317 typedef VALUE AppObjectPtr;
318 %typemap(in) AppObjectPtr {
319   $1 = (void *)$input;
320 }
321 %typemap(out) AppObjectPtr {
322   $result = (VALUE)$1;
323 }
324 #endif
325
326
327 %include "cdata.i"
328 #ifndef SWIGPERL
329 %include "file.i"
330 #endif
331 %include "typemaps.i"
332
333 %{
334 #include <stdbool.h>
335 #include <stdio.h>
336 #include <sys/stat.h>
337 #include <sys/utsname.h>
338 #include <sys/types.h>
339 #include <unistd.h>
340
341 #ifdef __GLIBC__
342 /* glibc's way of closing the file without freeing the file pointer */
343 extern int _IO_file_close_it(FILE *);
344 #else
345 #define _IO_file_close_it(fp) 0
346 #endif
347
348 /* argh, swig undefs bool for perl */
349 #ifndef bool
350 typedef int bool;
351 #endif
352
353 #include "pool.h"
354 #include "poolarch.h"
355 #include "solver.h"
356 #include "policy.h"
357 #include "solverdebug.h"
358 #include "repo_solv.h"
359 #include "chksum.h"
360 #include "selection.h"
361
362 #include "repo_write.h"
363 #ifdef ENABLE_RPMDB
364 #include "repo_rpmdb.h"
365 #endif
366 #ifdef ENABLE_DEBIAN
367 #include "repo_deb.h"
368 #endif
369 #ifdef ENABLE_RPMMD
370 #include "repo_rpmmd.h"
371 #include "repo_updateinfoxml.h"
372 #include "repo_deltainfoxml.h"
373 #include "repo_repomdxml.h"
374 #endif
375 #ifdef ENABLE_SUSEREPO
376 #include "repo_products.h"
377 #include "repo_susetags.h"
378 #include "repo_content.h"
379 #endif
380 #ifdef ENABLE_MDKREPO
381 #include "repo_mdk.h"
382 #endif
383 #ifdef ENABLE_ARCHREPO
384 #include "repo_arch.h"
385 #endif
386 #include "solv_xfopen.h"
387
388 /* for old ruby versions */
389 #ifndef RARRAY_PTR
390 #define RARRAY_PTR(ary) (RARRAY(ary)->ptr)
391 #endif
392 #ifndef RARRAY_LEN
393 #define RARRAY_LEN(ary) (RARRAY(ary)->len)
394 #endif
395
396 #define SOLVER_SOLUTION_ERASE                   -100
397 #define SOLVER_SOLUTION_REPLACE                 -101
398 #define SOLVER_SOLUTION_REPLACE_DOWNGRADE       -102
399 #define SOLVER_SOLUTION_REPLACE_ARCHCHANGE      -103
400 #define SOLVER_SOLUTION_REPLACE_VENDORCHANGE    -104
401
402 typedef struct chksum Chksum;
403 typedef void *AppObjectPtr;
404
405 typedef struct {
406   Pool *pool;
407   Id id;
408 } Dep;
409
410 typedef struct {
411   Pool *pool;
412   Id id;
413 } XSolvable;
414
415 typedef struct {
416   Solver *solv;
417   Id id;
418 } XRule;
419
420 typedef struct {
421   Repo *repo;
422   Id id;
423 } XRepodata;
424
425 typedef struct {
426   Pool *pool;
427   Id id;
428 } Pool_solvable_iterator;
429
430 typedef struct {
431   Pool *pool;
432   Id id;
433 } Pool_repo_iterator;
434
435 typedef struct {
436   Repo *repo;
437   Id id;
438 } Repo_solvable_iterator;
439
440 typedef struct {
441   Pool *pool;
442   int how;
443   Id what;
444 } Job;
445
446 typedef struct {
447   Solver *solv;
448   Id id;
449 } Problem;
450
451 typedef struct {
452   Solver *solv;
453   Id problemid;
454   Id id;
455 } Solution;
456
457 typedef struct {
458   Solver *solv;
459   Id problemid;
460   Id solutionid;
461   Id id;
462
463   Id type;
464   Id p;
465   Id rp;
466 } Solutionelement;
467
468 typedef struct {
469   Solver *solv;
470   Id rid;
471   Id type;
472   Id source;
473   Id target;
474   Id dep;
475 } Ruleinfo;
476
477 typedef struct {
478   Transaction *transaction;
479   int mode;
480   Id type;
481   int count;
482   Id fromid;
483   Id toid;
484 } TransactionClass;
485
486 typedef struct {
487   Pool *pool;
488   Queue q;
489   int flags;
490 } Selection;
491
492 typedef Dataiterator Datamatch;
493
494 %}
495
496 #ifdef SWIGRUBY
497 %mixin Dataiterator "Enumerable";
498 %mixin Pool_solvable_iterator "Enumerable";
499 %mixin Pool_repo_iterator "Enumerable";
500 %mixin Repo_solvable_iterator "Enumerable";
501 #endif
502
503 typedef int Id;
504
505 %include "knownid.h"
506
507 # from repodata.h
508 %constant Id SOLVID_META;
509 %constant Id SOLVID_POS;
510
511 %constant int REL_EQ;
512 %constant int REL_GT;
513 %constant int REL_LT;
514 %constant int REL_ARCH;
515
516 typedef struct {
517   Pool* const pool;
518 } Selection;
519
520 typedef struct {
521   Pool* const pool;
522   Id const id;
523 } Dep;
524
525 typedef struct {
526   Pool* const pool;
527   Id const id;
528 } XSolvable;
529
530 typedef struct {
531   Solver* const solv;
532   Id const type;
533   Id const dep;
534 } Ruleinfo;
535
536 typedef struct {
537   Solver* const solv;
538   Id const id;
539 } XRule;
540
541 typedef struct {
542   Repo* const repo;
543   Id const id;
544 } XRepodata;
545
546 # put before pool/repo so we can access the constructor
547 %nodefaultdtor Dataiterator;
548 typedef struct {} Dataiterator;
549 typedef struct {} Pool_solvable_iterator;
550 typedef struct {} Pool_repo_iterator;
551 typedef struct {} Repo_solvable_iterator;
552
553 %nodefaultctor Datamatch;
554 %nodefaultdtor Datamatch;
555 typedef struct {
556   Pool * const pool;
557   Repo * const repo;
558   Id const solvid;
559 } Datamatch;
560
561 %nodefaultctor Datapos;
562 typedef struct {
563   Repo * const repo;
564 } Datapos;
565
566 typedef struct {
567   Pool * const pool;
568   int how;
569   Id what;
570 } Job;
571
572 %nodefaultctor Pool;
573 %nodefaultdtor Pool;
574 typedef struct {
575   AppObjectPtr appdata;
576 } Pool;
577
578 %nodefaultctor Repo;
579 %nodefaultdtor Repo;
580 typedef struct {
581   Pool * const pool;
582   const char * const name;
583   int priority;
584   int subpriority;
585   int const nsolvables;
586   AppObjectPtr appdata;
587 } Repo;
588
589 %nodefaultctor Solver;
590 %nodefaultdtor Solver;
591 typedef struct {
592   Pool * const pool;
593 } Solver;
594
595 typedef struct {
596 } Chksum;
597
598 %rename(xfopen) solv_xfopen;
599 %rename(xfopen_fd) solv_xfopen_dup;
600
601 %nodefaultctor FILE;
602 typedef struct {
603 } FILE;
604
605 %newobject solv_xfopen;
606 %newobject solv_xfopen_dup;
607
608 FILE *solv_xfopen(const char *fn, const char *mode = 0);
609 FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode = 0);
610
611 %{
612   SWIGINTERN FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode) {
613     fd = dup(fd);
614     return fd == -1 ? 0 : solv_xfopen_fd(fn, fd, mode);
615   }
616 %}
617
618 typedef struct {
619   Solver * const solv;
620   Id const id;
621 } Problem;
622
623 typedef struct {
624   Solver * const solv;
625   Id const problemid;
626   Id const id;
627 } Solution;
628
629 typedef struct {
630   Solver *const solv;
631   Id const problemid;
632   Id const solutionid;
633   Id const id;
634   Id const type;
635 } Solutionelement;
636
637 %nodefaultctor Transaction;
638 %nodefaultdtor Transaction;
639 typedef struct {
640   Pool * const pool;
641 } Transaction;
642
643 typedef struct {
644   Transaction * const transaction;
645   Id const type;
646   Id const fromid;
647   Id const toid;
648   int const count;
649 } TransactionClass;
650
651 %extend FILE {
652   ~FILE() {
653     fclose($self);
654   }
655   int fileno() {
656     return fileno($self);
657   }
658   int dup() {
659     return dup(fileno($self));
660   }
661   bool flush() {
662     return fflush($self) == 0;
663   }
664   bool close() {
665     bool ret;
666     ret = fflush($self) == 0;
667     _IO_file_close_it($self);
668     return ret;
669   }
670 }
671
672 %extend Job {
673   static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
674   static const Id SOLVER_SOLVABLE_NAME = SOLVER_SOLVABLE_NAME;
675   static const Id SOLVER_SOLVABLE_PROVIDES = SOLVER_SOLVABLE_PROVIDES;
676   static const Id SOLVER_SOLVABLE_ONE_OF = SOLVER_SOLVABLE_ONE_OF;
677   static const Id SOLVER_SOLVABLE_REPO = SOLVER_SOLVABLE_REPO;
678   static const Id SOLVER_SOLVABLE_ALL = SOLVER_SOLVABLE_ALL;
679   static const Id SOLVER_SELECTMASK = SOLVER_SELECTMASK;
680   static const Id SOLVER_NOOP = SOLVER_NOOP;
681   static const Id SOLVER_INSTALL = SOLVER_INSTALL;
682   static const Id SOLVER_ERASE = SOLVER_ERASE;
683   static const Id SOLVER_UPDATE = SOLVER_UPDATE;
684   static const Id SOLVER_WEAKENDEPS = SOLVER_WEAKENDEPS;
685   static const Id SOLVER_NOOBSOLETES = SOLVER_NOOBSOLETES;
686   static const Id SOLVER_LOCK = SOLVER_LOCK;
687   static const Id SOLVER_DISTUPGRADE = SOLVER_DISTUPGRADE;
688   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
689   static const Id SOLVER_DROP_ORPHANED = SOLVER_DROP_ORPHANED;
690   static const Id SOLVER_USERINSTALLED = SOLVER_USERINSTALLED;
691   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
692   static const Id SOLVER_WEAK = SOLVER_WEAK;
693   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
694   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
695   static const Id SOLVER_SETEV = SOLVER_SETEV;
696   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
697   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
698   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
699   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
700   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
701   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
702
703   Job(Pool *pool, int how, Id what) {
704     Job *job = solv_calloc(1, sizeof(*job));
705     job->pool = pool;
706     job->how = how;
707     job->what = what;
708     return job;
709   }
710
711   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
712   %newobject solvables;
713   Queue solvables() {
714     Queue q;
715     queue_init(&q);
716     pool_job2solvables($self->pool, &q, $self->how, $self->what);
717     return q;
718   }
719
720   bool __eq__(Job *j) {
721     return $self->pool == j->pool && $self->how == j->how && $self->what == j->what;
722   }
723   bool __ne__(Job *j) {
724     return !Job___eq__($self, j);
725   }
726 #if defined(SWIGPERL)
727   %rename("str") __str__;
728 #endif
729   const char *__str__() {
730     return pool_job2str($self->pool, $self->how, $self->what, 0);
731   }
732   const char *__repr__() {
733     const char *str = pool_job2str($self->pool, $self->how, $self->what, ~0);
734     return pool_tmpjoin($self->pool, "<Job ", str, ">");
735   }
736 }
737
738 %extend Selection {
739   static const Id SELECTION_NAME = SELECTION_NAME;
740   static const Id SELECTION_PROVIDES = SELECTION_PROVIDES;
741   static const Id SELECTION_FILELIST = SELECTION_FILELIST;
742   static const Id SELECTION_GLOB = SELECTION_GLOB;
743   static const Id SELECTION_NOCASE = SELECTION_NOCASE;
744   static const Id SELECTION_INSTALLED_ONLY = SELECTION_INSTALLED_ONLY;
745   static const Id SELECTION_FLAT = SELECTION_FLAT;
746   static const Id SELECTION_SOURCE_ONLY = SELECTION_SOURCE_ONLY;
747   static const Id SELECTION_WITH_SOURCE = SELECTION_WITH_SOURCE;
748
749   Selection(Pool *pool) {
750     Selection *s;
751     s = solv_calloc(1, sizeof(*s));
752     s->pool = pool;
753     return s;
754   }
755
756   ~Selection() {
757     queue_free(&$self->q);
758     solv_free($self);
759   }
760   int flags() {
761     return $self->flags;
762   }
763   void make(const char *name, int flags) {
764     $self->flags = selection_make($self->pool, &$self->q, name, flags);
765   }
766 #ifdef SWIGRUBY
767   %rename("isempty?") isempty;
768 #endif
769   bool isempty() {
770     return $self->q.count == 0;
771   }
772   void limit(Selection *lsel) {
773     if ($self->pool != lsel->pool)
774       queue_empty(&$self->q);
775     else
776       selection_limit($self->pool, &$self->q, &lsel->q);
777   }
778   void add(Selection *lsel) {
779     if ($self->pool == lsel->pool)
780       {
781         selection_add($self->pool, &$self->q, &lsel->q);
782         $self->flags |= lsel->flags;
783       }
784   }
785   void addsimple(Id how, Id what) {
786     queue_push2(&$self->q, how, what);
787   }
788   %typemap(out) Queue jobs Queue2Array(Job *, 2, new_Job(arg1->pool, id, idp[1]));
789   %newobject jobs;
790   Queue jobs(int flags) {
791     Queue q;
792     int i;
793     queue_init_clone(&q, &$self->q);
794     for (i = 0; i < q.count; i += 2)
795       q.elements[i] |= flags;
796     return q;
797   }
798
799   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
800   %newobject solvables;
801   Queue solvables() {
802     Queue q;
803     queue_init(&q);
804     selection_solvables($self->pool, &$self->q, &q);
805     return q;
806   }
807
808 #if defined(SWIGPERL)
809   %rename("str") __str__;
810 #endif
811   const char *__str__() {
812     return pool_selection2str($self->pool, &$self->q, 0);
813   }
814   const char *__repr__() {
815     const char *str = pool_selection2str($self->pool, &$self->q, ~0);
816     return pool_tmpjoin($self->pool, "<Selection ", str, ">");
817   }
818 }
819
820 %extend Chksum {
821   Chksum(Id type) {
822     return (Chksum *)solv_chksum_create(type);
823   }
824   Chksum(Id type, const char *hex) {
825     unsigned char buf[64];
826     int l = solv_chksum_len(type);
827     if (!l)
828       return 0;
829     if (solv_hex2bin(&hex, buf, sizeof(buf)) != l || hex[0])
830       return 0;
831     return (Chksum *)solv_chksum_create_from_bin(type, buf);
832   }
833   ~Chksum() {
834     solv_chksum_free($self, 0);
835   }
836   Id const type;
837   %{
838   SWIGINTERN Id Chksum_type_get(Chksum *chksum) {
839     return solv_chksum_get_type(chksum);
840   }
841   %}
842   void add(const char *str) {
843     solv_chksum_add($self, str, strlen((char *)str));
844   }
845   void add_fp(FILE *fp) {
846     char buf[4096];
847     int l;
848     while ((l = fread(buf, 1, sizeof(buf), fp)) > 0)
849       solv_chksum_add($self, buf, l);
850     rewind(fp);         /* convenience */
851   }
852   void add_fd(int fd) {
853     char buf[4096];
854     int l;
855     while ((l = read(fd, buf, sizeof(buf))) > 0)
856       solv_chksum_add($self, buf, l);
857     lseek(fd, 0, 0);    /* convenience */
858   }
859   void add_stat(const char *filename) {
860     struct stat stb;
861     if (stat(filename, &stb))
862       memset(&stb, 0, sizeof(stb));
863     solv_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
864     solv_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
865     solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
866     solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
867   }
868   void add_fstat(int fd) {
869     struct stat stb;
870     if (fstat(fd, &stb))
871       memset(&stb, 0, sizeof(stb));
872     solv_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
873     solv_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
874     solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
875     solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
876   }
877   SWIGCDATA raw() {
878     int l;
879     const unsigned char *b;
880     b = solv_chksum_get($self, &l);
881     return cdata_void((void *)b, l);
882   }
883   %newobject hex;
884   char *hex() {
885     int l;
886     const unsigned char *b;
887     char *ret;
888
889     b = solv_chksum_get($self, &l);
890     ret = solv_malloc(2 * l + 1);
891     solv_bin2hex(b, l, ret);
892     return ret;
893   }
894
895   bool __eq__(Chksum *chk) {
896     int l;
897     const unsigned char *b, *bo;
898     if (!chk)
899       return 0;
900     if (solv_chksum_get_type($self) != solv_chksum_get_type(chk))
901       return 0;
902     b = solv_chksum_get($self, &l);
903     bo = solv_chksum_get(chk, 0);
904     return memcmp(b, bo, l) == 0;
905   }
906   bool __ne__(Chksum *chk) {
907     return !Chksum___eq__($self, chk);
908   }
909 #if defined(SWIGRUBY)
910   %rename("to_s") __str__;
911   %rename("inspect") __repr__;
912 #endif
913 #if defined(SWIGPERL)
914   %rename("str") __str__;
915 #endif
916   %newobject __str__;
917   const char *__str__() {
918     const char *str;
919     const char *h = 0;
920     if (solv_chksum_isfinished($self))
921       h = Chksum_hex($self);
922     str = solv_dupjoin(solv_chksum_type2str(solv_chksum_get_type($self)), ":", h ? h : "unfinished");
923     solv_free((void *)h);
924     return str;
925   }
926   %newobject __repr__;
927   const char *__repr__() {
928     const char *h = Chksum___str__($self);
929     const char *str = solv_dupjoin("<Chksum ", h, ">");
930     solv_free((void *)h);
931     return str;
932   }
933 }
934
935 %extend Pool {
936   Pool() {
937     Pool *pool = pool_create();
938     return pool;
939   }
940   ~Pool() {
941   }
942   void set_debuglevel(int level) {
943     pool_setdebuglevel($self, level);
944   }
945   int set_flag(int flag, int value) {
946     return pool_set_flag($self, flag, value);
947   }
948   int get_flag(int flag) {
949     return pool_get_flag($self, flag);
950   }
951   void set_rootdir(const char *rootdir) {
952     pool_set_rootdir($self, rootdir);
953   }
954   const char *get_rootdir(int flag) {
955     return pool_get_rootdir($self);
956   }
957 #if defined(SWIGPYTHON)
958   %{
959   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
960     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
961     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
962     PyObject *result = PyEval_CallObject((PyObject *)d, args);
963     int ecode = 0;
964     int vresult = 0;
965     Py_DECREF(args);
966     if (!result)
967       return 0; /* exception */
968     ecode = SWIG_AsVal_int(result, &vresult);
969     Py_DECREF(result);
970     return SWIG_IsOK(ecode) ? vresult : 0;
971   }
972   %}
973   void set_loadcallback(PyObject *callable) {
974     if ($self->loadcallback == loadcallback) {
975       PyObject *obj = $self->loadcallbackdata;
976       Py_DECREF(obj);
977     }
978     if (callable) {
979       Py_INCREF(callable);
980     }
981     pool_setloadcallback($self, callable ? loadcallback : 0, callable);
982   }
983 #endif
984 #if defined(SWIGPERL)
985 %{
986   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
987     int count;
988     int ret = 0;
989     dSP;
990     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
991
992     ENTER;
993     SAVETMPS;
994     PUSHMARK(SP);
995     XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_OWNER | SWIG_SHADOW));
996     PUTBACK;
997     count = perl_call_sv((SV *)d, G_EVAL|G_SCALAR);
998     SPAGAIN;
999     if (count)
1000       ret = POPi;
1001     PUTBACK;
1002     FREETMPS;
1003     LEAVE;
1004     return ret;
1005   }
1006 %}
1007   void set_loadcallback(SV *callable) {
1008     if ($self->loadcallback == loadcallback)
1009       SvREFCNT_dec($self->loadcallbackdata);
1010     if (callable)
1011       SvREFCNT_inc(callable);
1012     pool_setloadcallback($self, callable ? loadcallback : 0, callable);
1013   }
1014 #endif
1015
1016 #if defined(SWIGRUBY)
1017 %{
1018   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
1019     XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
1020     VALUE callable = (VALUE)d;
1021     VALUE rd = SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0);
1022     VALUE res = rb_funcall(callable, rb_intern("call"), 1, rd);
1023     return res == Qtrue;
1024   }
1025   SWIGINTERN void mark_Pool(void *ptr) {
1026     Pool *pool = ptr;
1027     if (pool->loadcallback == loadcallback && pool->loadcallbackdata) {
1028       VALUE callable = (VALUE)pool->loadcallbackdata;
1029       rb_gc_mark(callable);
1030     }
1031   }
1032 %}
1033   %typemap(in, numinputs=0) VALUE callable {
1034     $1 = rb_block_given_p() ? rb_block_proc() : 0;
1035   }
1036   void set_loadcallback(VALUE callable) {
1037     pool_setloadcallback($self, callable ? loadcallback : 0, (void *)callable);
1038   }
1039 #endif
1040
1041   void free() {
1042     Pool_set_loadcallback($self, 0);
1043     pool_free($self);
1044   }
1045   Id str2id(const char *str, bool create=1) {
1046     return pool_str2id($self, str, create);
1047   }
1048   Dep *Dep(const char *str, bool create=1) {
1049     Id id = pool_str2id($self, str, create);
1050     return new_Dep($self, id);
1051   }
1052   const char *id2str(Id id) {
1053     return pool_id2str($self, id);
1054   }
1055   const char *dep2str(Id id) {
1056     return pool_dep2str($self, id);
1057   }
1058   Id rel2id(Id name, Id evr, int flags, bool create=1) {
1059     return pool_rel2id($self, name, evr, flags, create);
1060   }
1061   Id id2langid(Id id, const char *lang, bool create=1) {
1062     return pool_id2langid($self, id, lang, create);
1063   }
1064   void setarch(const char *arch = 0) {
1065     struct utsname un;
1066     if (!arch) {
1067       if (uname(&un)) {
1068         perror("uname");
1069         return;
1070       }
1071       arch = un.machine;
1072     }
1073     pool_setarch($self, arch);
1074   }
1075   Repo *add_repo(const char *name) {
1076     return repo_create($self, name);
1077   }
1078   const char *lookup_str(Id entry, Id keyname) {
1079     return pool_lookup_str($self, entry, keyname);
1080   }
1081   Id lookup_id(Id entry, Id keyname) {
1082     return pool_lookup_id($self, entry, keyname);
1083   }
1084   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
1085     return pool_lookup_num($self, entry, keyname, notfound);
1086   }
1087   bool lookup_void(Id entry, Id keyname) {
1088     return pool_lookup_void($self, entry, keyname);
1089   }
1090   %newobject lookup_checksum;
1091   Chksum *lookup_checksum(Id entry, Id keyname) {
1092     Id type = 0;
1093     const unsigned char *b = pool_lookup_bin_checksum($self, entry, keyname, &type);
1094     return solv_chksum_create_from_bin(type, b);
1095   }
1096
1097   %newobject Dataiterator;
1098   Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
1099     return new_Dataiterator($self, 0, p, key, match, flags);
1100   }
1101   const char *solvid2str(Id solvid) {
1102     return pool_solvid2str($self, solvid);
1103   }
1104   void addfileprovides() {
1105     pool_addfileprovides($self);
1106   }
1107   Queue addfileprovides_queue() {
1108     Queue r;
1109     queue_init(&r);
1110     pool_addfileprovides_queue($self, &r, 0);
1111     return r;
1112   }
1113   void createwhatprovides() {
1114     pool_createwhatprovides($self);
1115   }
1116
1117   XSolvable *id2solvable(Id id) {
1118     return new_XSolvable($self, id);
1119   }
1120   %newobject solvables;
1121   Pool_solvable_iterator * const solvables;
1122   %{
1123   SWIGINTERN Pool_solvable_iterator * Pool_solvables_get(Pool *pool) {
1124     return new_Pool_solvable_iterator(pool);
1125   }
1126   %}
1127   %newobject solvables_iter;
1128   Pool_solvable_iterator * solvables_iter() {
1129     return new_Pool_solvable_iterator($self);
1130   }
1131
1132   Repo *id2repo(Id id) {
1133     if (id < 1 || id >= $self->nrepos)
1134       return 0;
1135     return pool_id2repo($self, id);
1136   }
1137   %newobject repos;
1138   Pool_repo_iterator * const repos;
1139   %{
1140   SWIGINTERN Pool_repo_iterator * Pool_repos_get(Pool *pool) {
1141     return new_Pool_repo_iterator(pool);
1142   }
1143   %}
1144   %newobject repos_iter;
1145   Pool_repo_iterator * repos_iter() {
1146     return new_Pool_repo_iterator($self);
1147   }
1148
1149   Repo *installed;
1150   %{
1151   SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
1152     pool_set_installed(pool, installed);
1153   }
1154   Repo *Pool_installed_get(Pool *pool) {
1155     return pool->installed;
1156   }
1157   %}
1158
1159   Queue matchprovidingids(const char *match, int flags) {
1160     Pool *pool = $self;
1161     Queue q;
1162     Id id;
1163     queue_init(&q);
1164     if (!flags) {
1165       for (id = 1; id < pool->ss.nstrings; id++)
1166         if (pool->whatprovides[id])
1167           queue_push(&q, id);
1168     } else {
1169       Datamatcher ma;
1170       if (!datamatcher_init(&ma, match, flags)) {
1171         for (id = 1; id < pool->ss.nstrings; id++)
1172           if (pool->whatprovides[id] && datamatcher_match(&ma, pool_id2str(pool, id)))
1173             queue_push(&q, id);
1174         datamatcher_free(&ma);
1175       }
1176     }
1177     return q;
1178   }
1179
1180   Job *Job(int how, Id what) {
1181     return new_Job($self, how, what);
1182   }
1183
1184   %typemap(out) Queue whatprovides Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
1185   %newobject whatprovides;
1186   Queue whatprovides(Id dep) {
1187     Pool *pool = $self;
1188     Queue q;
1189     Id p, pp;
1190     queue_init(&q);
1191     FOR_PROVIDES(p, pp, dep)
1192       queue_push(&q, p);
1193     return q;
1194   }
1195
1196   Id towhatprovides(Queue q) {
1197     return pool_queuetowhatprovides($self, &q);
1198   }
1199
1200 #ifdef SWIGRUBY
1201   %rename("isknownarch?") isknownarch;
1202 #endif
1203   bool isknownarch(Id id) {
1204     Pool *pool = $self;
1205     if (!id || id == ID_EMPTY)
1206       return 0;
1207     if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
1208       return 1;
1209     if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
1210       return 0;
1211     return 1;
1212   }
1213
1214   %newobject Solver;
1215   Solver *Solver() {
1216     return solver_create($self);
1217   }
1218
1219   %newobject Selection;
1220   Selection *Selection() {
1221     return new_Selection($self);
1222   }
1223   %newobject select;
1224   Selection *select(const char *name, int flags) {
1225     Selection *sel = new_Selection($self);
1226     sel->flags = selection_make($self, &sel->q, name, flags);
1227     return sel;
1228   }
1229 }
1230
1231 %extend Repo {
1232   static const int REPO_REUSE_REPODATA = REPO_REUSE_REPODATA;
1233   static const int REPO_NO_INTERNALIZE = REPO_NO_INTERNALIZE;
1234   static const int REPO_LOCALPOOL = REPO_LOCALPOOL;
1235   static const int REPO_USE_LOADING = REPO_USE_LOADING;
1236   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
1237   static const int REPO_USE_ROOTDIR  = REPO_USE_ROOTDIR;
1238   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
1239 #ifdef ENABLE_SUSEREPO
1240   static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES;     /* repo_susetags */
1241 #endif
1242
1243   void free(bool reuseids = 0) {
1244     repo_free($self, reuseids);
1245   }
1246   void empty(bool reuseids = 0) {
1247     repo_empty($self, reuseids);
1248   }
1249 #ifdef SWIGRUBY
1250   %rename("isempty?") isempty;
1251 #endif
1252   bool isempty() {
1253     return !$self->nsolvables;
1254   }
1255   bool add_solv(const char *name, int flags = 0) {
1256     FILE *fp = fopen(name, "r");
1257     int r;
1258     if (!fp)
1259       return 0;
1260     r = repo_add_solv($self, fp, flags);
1261     fclose(fp);
1262     return r == 0;
1263   }
1264   bool add_solv(FILE *fp, int flags = 0) {
1265     return repo_add_solv($self, fp, flags) == 0;
1266   }
1267
1268   XSolvable *add_solvable() {
1269     Id solvid = repo_add_solvable($self);
1270     return new_XSolvable($self->pool, solvid);
1271   }
1272
1273 #ifdef ENABLE_RPMDB
1274   bool add_rpmdb(Repo *ref, int flags = 0) {
1275     return repo_add_rpmdb($self, ref, flags);
1276   }
1277   Id add_rpm(const char *name, int flags = 0) {
1278     return repo_add_rpm($self, name, flags);
1279   }
1280 #endif
1281 #ifdef ENABLE_RPMMD
1282   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
1283     return repo_add_rpmmd($self, fp, language, flags);
1284   }
1285   bool add_repomdxml(FILE *fp, int flags = 0) {
1286     return repo_add_repomdxml($self, fp, flags);
1287   }
1288   bool add_updateinfoxml(FILE *fp, int flags = 0) {
1289     return repo_add_updateinfoxml($self, fp, flags);
1290   }
1291   bool add_deltainfoxml(FILE *fp, int flags = 0) {
1292     return repo_add_deltainfoxml($self, fp, flags);
1293   }
1294 #endif
1295 #ifdef ENABLE_DEBIAN
1296   bool add_debdb(int flags = 0) {
1297     return repo_add_debdb($self, flags);
1298   }
1299   Id add_deb(const char *name, int flags = 0) {
1300     return repo_add_deb($self, name, flags);
1301   }
1302 #endif
1303 #ifdef ENABLE_SUSEREPO
1304   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
1305     return repo_add_susetags($self, fp, defvendor, language, flags);
1306   }
1307   bool add_content(FILE *fp, int flags = 0) {
1308     return repo_add_content($self, fp, flags);
1309   }
1310   bool add_products(const char *proddir, int flags = 0) {
1311     return repo_add_products($self, proddir, flags);
1312   }
1313 #endif
1314 #ifdef ENABLE_MDKREPO
1315   bool add_mdk(FILE *fp, int flags = 0) {
1316     return repo_add_mdk($self, fp, flags);
1317   }
1318   bool add_mdk_info(FILE *fp, int flags = 0) {
1319     return repo_add_mdk($self, fp, flags);
1320   }
1321 #endif
1322 #ifdef ENABLE_ARCHREPO
1323   bool add_arch_repo(FILE *fp, int flags = 0) {
1324     return repo_add_arch_repo($self, fp, flags);
1325   }
1326   Id add_arch_pkg(const char *name, int flags = 0) {
1327     return repo_add_arch_pkg($self, name, flags);
1328   }
1329 #endif
1330   void internalize() {
1331     repo_internalize($self);
1332   }
1333   const char *lookup_str(Id entry, Id keyname) {
1334     return repo_lookup_str($self, entry, keyname);
1335   }
1336   Id lookup_id(Id entry, Id keyname) {
1337     return repo_lookup_id($self, entry, keyname);
1338   }
1339   unsigned long long lookup_num(Id entry, Id keyname, unsigned long long notfound = 0) {
1340     return repo_lookup_num($self, entry, keyname, notfound);
1341   }
1342   void write(FILE *fp) {
1343     repo_write($self, fp);
1344   }
1345   # HACK, remove if no longer needed!
1346   bool write_first_repodata(FILE *fp) {
1347     int oldnrepodata = $self->nrepodata;
1348     $self->nrepodata = oldnrepodata > 2 ? 2 : oldnrepodata;
1349     repo_write($self, fp);
1350     $self->nrepodata = oldnrepodata;
1351     return 1;
1352   }
1353
1354   %newobject Dataiterator;
1355   Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
1356     return new_Dataiterator($self->pool, $self, p, key, match, flags);
1357   }
1358
1359   Id const id;
1360   %{
1361   SWIGINTERN Id Repo_id_get(Repo *repo) {
1362     return repo->repoid;
1363   }
1364   %}
1365   Repo_solvable_iterator * const solvables;
1366   %{
1367   SWIGINTERN Repo_solvable_iterator * Repo_solvables_get(Repo *repo) {
1368     return new_Repo_solvable_iterator(repo);
1369   }
1370   %}
1371   %newobject solvables_iter;
1372   Repo_solvable_iterator *solvables_iter() {
1373     return new_Repo_solvable_iterator($self);
1374   }
1375
1376   XRepodata *add_repodata(int flags = 0) {
1377     Repodata *rd = repo_add_repodata($self, flags);
1378     return new_XRepodata($self, rd->repodataid);
1379   }
1380
1381   void create_stubs() {
1382     Repodata *data;
1383     if (!$self->nrepodata)
1384       return;
1385     data = repo_id2repodata($self, $self->nrepodata - 1);
1386     if (data->state != REPODATA_STUB)
1387       repodata_create_stubs(data);
1388   }
1389 #ifdef SWIGRUBY
1390   %rename("iscontiguous?") iscontiguous;
1391 #endif
1392   bool iscontiguous() {
1393     int i;
1394     for (i = $self->start; i < $self->end; i++)
1395       if ($self->pool->solvables[i].repo != $self)
1396         return 0;
1397     return 1;
1398   }
1399   XRepodata *first_repodata() {
1400     Repodata *data;
1401     int i;
1402     if ($self->nrepodata < 2)
1403       return 0;
1404     /* make sure all repodatas but the first are extensions */
1405     data = repo_id2repodata($self, 1);
1406     if (data->loadcallback)
1407        return 0;
1408     for (i = 2; i < $self->nrepodata; i++)
1409       {
1410         data = repo_id2repodata($self, i);
1411         if (!data->loadcallback)
1412           return 0;       /* oops, not an extension */
1413       }
1414     return new_XRepodata($self, 1);
1415   }
1416
1417   bool __eq__(Repo *repo) {
1418     return $self == repo;
1419   }
1420   bool __ne__(Repo *repo) {
1421     return $self != repo;
1422   }
1423 #if defined(SWIGPERL)
1424   %rename("str") __str__;
1425 #endif
1426   %newobject __str__;
1427   const char *__str__() {
1428     char buf[20];
1429     if ($self->name)
1430       return solv_strdup($self->name);
1431     sprintf(buf, "Repo#%d", $self->repoid);
1432     return solv_strdup(buf);
1433   }
1434   %newobject __repr__;
1435   const char *__repr__() {
1436     char buf[20];
1437     if ($self->name)
1438       {
1439         sprintf(buf, "<Repo #%d ", $self->repoid);
1440         return solv_dupjoin(buf, $self->name, ">");
1441       }
1442     sprintf(buf, "<Repo #%d>", $self->repoid);
1443     return solv_strdup(buf);
1444   }
1445 }
1446
1447 %extend Dataiterator {
1448   static const int SEARCH_STRING = SEARCH_STRING;
1449   static const int SEARCH_SUBSTRING = SEARCH_SUBSTRING;
1450   static const int SEARCH_GLOB = SEARCH_GLOB;
1451   static const int SEARCH_REGEX = SEARCH_REGEX;
1452   static const int SEARCH_NOCASE = SEARCH_NOCASE;
1453   static const int SEARCH_FILES = SEARCH_FILES;
1454   static const int SEARCH_COMPLETE_FILELIST = SEARCH_COMPLETE_FILELIST;
1455
1456   Dataiterator(Pool *pool, Repo *repo, Id p, Id key, const char *match, int flags) {
1457     Dataiterator *di = solv_calloc(1, sizeof(*di));
1458     dataiterator_init(di, pool, repo, p, key, match, flags);
1459     return di;
1460   }
1461   ~Dataiterator() {
1462     dataiterator_free($self);
1463     solv_free($self);
1464   }
1465 #if defined(SWIGPYTHON)
1466   %newobject __iter__;
1467   Dataiterator *__iter__() {
1468     Dataiterator *ndi;
1469     ndi = solv_calloc(1, sizeof(*ndi));
1470     dataiterator_init_clone(ndi, $self);
1471     return ndi;
1472   }
1473   %rename("next") __next__();
1474   %exception __next__ {
1475     $action
1476     if (!result) {
1477       PyErr_SetString(PyExc_StopIteration,"no more matches");
1478       return NULL;
1479     }
1480   }
1481 #endif
1482
1483 #ifdef SWIGPERL
1484   perliter(solv::Dataiterator)
1485 #endif
1486
1487   %newobject __next__;
1488   Datamatch *__next__() {
1489     Dataiterator *ndi;
1490     if (!dataiterator_step($self)) {
1491       return 0;
1492     }
1493     ndi = solv_calloc(1, sizeof(*ndi));
1494     dataiterator_init_clone(ndi, $self);
1495     return ndi;
1496   }
1497 #ifdef SWIGRUBY
1498   void each() {
1499     Datamatch *d;
1500     while ((d = Dataiterator___next__($self)) != 0) {
1501       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(d), SWIGTYPE_p_Datamatch, SWIG_POINTER_OWN | 0));
1502     }
1503   }
1504 #endif
1505   void prepend_keyname(Id key) {
1506     dataiterator_prepend_keyname($self, key);
1507   }
1508   void skip_solvable() {
1509     dataiterator_skip_solvable($self);
1510   }
1511 }
1512
1513 %extend Datapos {
1514   Id lookup_id(Id keyname) {
1515     Pool *pool = $self->repo->pool;
1516     Datapos oldpos = pool->pos;
1517     Id r;
1518     pool->pos = *$self;
1519     r = pool_lookup_id(pool, SOLVID_POS, keyname);
1520     pool->pos = oldpos;
1521     return r;
1522   }
1523   const char *lookup_str(Id keyname) {
1524     Pool *pool = $self->repo->pool;
1525     Datapos oldpos = pool->pos;
1526     const char *r;
1527     pool->pos = *$self;
1528     r = pool_lookup_str(pool, SOLVID_POS, keyname);
1529     pool->pos = oldpos;
1530     return r;
1531   }
1532   %newobject lookup_checksum;
1533   Chksum *lookup_checksum(Id keyname) {
1534     Pool *pool = $self->repo->pool;
1535     Datapos oldpos = pool->pos;
1536     Id type = 0;
1537     const unsigned char *b;
1538     pool->pos = *$self;
1539     b = pool_lookup_bin_checksum(pool, SOLVID_POS, keyname, &type);
1540     pool->pos = oldpos;
1541     return solv_chksum_create_from_bin(type, b);
1542   }
1543   const char *lookup_deltaseq() {
1544     Pool *pool = $self->repo->pool;
1545     Datapos oldpos = pool->pos;
1546     const char *seq;
1547     pool->pos = *$self;
1548     seq = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NAME);
1549     if (seq) {
1550       seq = pool_tmpjoin(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_EVR));
1551       seq = pool_tmpappend(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NUM));
1552     }
1553     pool->pos = oldpos;
1554     return seq;
1555   }
1556   const char *lookup_deltalocation() {
1557     Pool *pool = $self->repo->pool;
1558     Datapos oldpos = pool->pos;
1559     const char *loc;
1560     pool->pos = *$self;
1561     loc = pool_lookup_deltalocation(pool, SOLVID_POS);
1562     pool->pos = oldpos;
1563     return loc;
1564   }
1565 }
1566
1567 %extend Datamatch {
1568   ~Datamatch() {
1569     dataiterator_free($self);
1570     solv_free($self);
1571   }
1572   %newobject solvable;
1573   XSolvable * const solvable;
1574   %{
1575   SWIGINTERN XSolvable *Datamatch_solvable_get(Dataiterator *di) {
1576     return new_XSolvable(di->pool, di->solvid);
1577   }
1578   %}
1579   Id key_id() {
1580     return $self->key->name;
1581   }
1582   const char *key_idstr() {
1583     return pool_id2str($self->pool, $self->key->name);
1584   }
1585   Id type_id() {
1586     return $self->key->type;
1587   }
1588   const char *type_idstr() {
1589     return pool_id2str($self->pool, $self->key->type);
1590   }
1591   Id id() {
1592      return $self->kv.id;
1593   }
1594   const char *idstr() {
1595      return pool_id2str($self->pool, $self->kv.id);
1596   }
1597   const char *str() {
1598      return $self->kv.str;
1599   }
1600   int num() {
1601      return $self->kv.num;
1602   }
1603   int num2() {
1604      return $self->kv.num2;
1605   }
1606   %newobject pos;
1607   Datapos *pos() {
1608     Pool *pool = $self->pool;
1609     Datapos *pos, oldpos = pool->pos;
1610     dataiterator_setpos($self);
1611     pos = solv_calloc(1, sizeof(*pos));
1612     *pos = pool->pos;
1613     pool->pos = oldpos;
1614     return pos;
1615   }
1616   %newobject parentpos;
1617   Datapos *parentpos() {
1618     Pool *pool = $self->pool;
1619     Datapos *pos, oldpos = pool->pos;
1620     dataiterator_setpos_parent($self);
1621     pos = solv_calloc(1, sizeof(*pos));
1622     *pos = pool->pos;
1623     pool->pos = oldpos;
1624     return pos;
1625   }
1626   void setpos() {
1627     dataiterator_setpos($self);
1628   }
1629   void setpos_parent() {
1630     dataiterator_setpos_parent($self);
1631   }
1632 }
1633
1634 %extend Pool_solvable_iterator {
1635   Pool_solvable_iterator(Pool *pool) {
1636     Pool_solvable_iterator *s;
1637     s = solv_calloc(1, sizeof(*s));
1638     s->pool = pool;
1639     return s;
1640   }
1641 #if defined(SWIGPYTHON)
1642   %newobject __iter__;
1643   Pool_solvable_iterator *__iter__() {
1644     Pool_solvable_iterator *s;
1645     s = solv_calloc(1, sizeof(*s));
1646     *s = *$self;
1647     return s;
1648   }
1649   %rename("next") __next__();
1650   %exception __next__ {
1651     $action
1652     if (!result) {
1653       PyErr_SetString(PyExc_StopIteration,"no more matches");
1654       return NULL;
1655     }
1656   }
1657 #endif
1658
1659 #ifdef SWIGPERL
1660   perliter(solv::Pool_solvable_iterator)
1661 #endif
1662   %newobject __next__;
1663   XSolvable *__next__() {
1664     Pool *pool = $self->pool;
1665     if ($self->id >= pool->nsolvables)
1666       return 0;
1667     while (++$self->id < pool->nsolvables)
1668       if (pool->solvables[$self->id].repo)
1669         return new_XSolvable(pool, $self->id);
1670     return 0;
1671   }
1672 #ifdef SWIGRUBY
1673   void each() {
1674     XSolvable *n;
1675     while ((n = Pool_solvable_iterator___next__($self)) != 0) {
1676       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
1677     }
1678   }
1679 #endif
1680   %newobject __getitem__;
1681   XSolvable *__getitem__(Id key) {
1682     Pool *pool = $self->pool;
1683     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo)
1684       return new_XSolvable(pool, key);
1685     return 0;
1686   }
1687   int __len__() {
1688     return $self->pool->nsolvables;
1689   }
1690 }
1691
1692 %extend Pool_repo_iterator {
1693   Pool_repo_iterator(Pool *pool) {
1694     Pool_repo_iterator *s;
1695     s = solv_calloc(1, sizeof(*s));
1696     s->pool = pool;
1697     return s;
1698   }
1699 #if defined(SWIGPYTHON)
1700   %newobject __iter__;
1701   Pool_repo_iterator *__iter__() {
1702     Pool_repo_iterator *s;
1703     s = solv_calloc(1, sizeof(*s));
1704     *s = *$self;
1705     return s;
1706   }
1707   %rename("next") __next__();
1708   %exception __next__ {
1709     $action
1710     if (!result) {
1711       PyErr_SetString(PyExc_StopIteration,"no more matches");
1712       return NULL;
1713     }
1714   }
1715 #endif
1716   %newobject __next__;
1717   Repo *__next__() {
1718     Pool *pool = $self->pool;
1719     if ($self->id >= pool->nrepos)
1720       return 0;
1721     while (++$self->id < pool->nrepos) {
1722       Repo *r = pool_id2repo(pool, $self->id);
1723       if (r)
1724         return r;
1725     }
1726     return 0;
1727   }
1728 #ifdef SWIGRUBY
1729   void each() {
1730     Repo *n;
1731     while ((n = Pool_repo_iterator___next__($self)) != 0) {
1732       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_Repo, SWIG_POINTER_OWN | 0));
1733     }
1734   }
1735 #endif
1736   Repo *__getitem__(Id key) {
1737     Pool *pool = $self->pool;
1738     if (key > 0 && key < pool->nrepos)
1739       return pool_id2repo(pool, key);
1740     return 0;
1741   }
1742   int __len__() {
1743     return $self->pool->nrepos;
1744   }
1745 }
1746
1747 %extend Repo_solvable_iterator {
1748   Repo_solvable_iterator(Repo *repo) {
1749     Repo_solvable_iterator *s;
1750     s = solv_calloc(1, sizeof(*s));
1751     s->repo = repo;
1752     return s;
1753   }
1754 #if defined(SWIGPYTHON)
1755   %newobject __iter__;
1756   Repo_solvable_iterator *__iter__() {
1757     Repo_solvable_iterator *s;
1758     s = solv_calloc(1, sizeof(*s));
1759     *s = *$self;
1760     return s;
1761   }
1762   %rename("next") __next__();
1763   %exception __next__ {
1764     $action
1765     if (!result) {
1766       PyErr_SetString(PyExc_StopIteration,"no more matches");
1767       return NULL;
1768     }
1769   }
1770 #endif
1771   %newobject __next__;
1772   XSolvable *__next__() {
1773     Repo *repo = $self->repo;
1774     Pool *pool = repo->pool;
1775     if (repo->start > 0 && $self->id < repo->start)
1776       $self->id = repo->start - 1;
1777     if ($self->id >= repo->end)
1778       return 0;
1779     while (++$self->id < repo->end)
1780       if (pool->solvables[$self->id].repo == repo)
1781         return new_XSolvable(pool, $self->id);
1782     return 0;
1783   }
1784 #ifdef SWIGRUBY
1785   void each() {
1786     XSolvable *n;
1787     while ((n = Repo_solvable_iterator___next__($self)) != 0) {
1788       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
1789     }
1790   }
1791 #endif
1792   %newobject __getitem__;
1793   XSolvable *__getitem__(Id key) {
1794     Repo *repo = $self->repo;
1795     Pool *pool = repo->pool;
1796     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo == repo)
1797       return new_XSolvable(pool, key);
1798     return 0;
1799   }
1800   int __len__() {
1801     return $self->repo->pool->nsolvables;
1802   }
1803 }
1804
1805 %extend Dep {
1806   Dep(Pool *pool, Id id) {
1807     Dep *s;
1808     if (!id)
1809       return 0;
1810     s = solv_calloc(1, sizeof(*s));
1811     s->pool = pool;
1812     s->id = id;
1813     return s;
1814   }
1815   const char *str() {
1816     return pool_dep2str($self->pool, $self->id);
1817   }
1818   bool __eq__(Dep *s) {
1819     return $self->pool == s->pool && $self->id == s->id;
1820   }
1821   bool __ne__(Dep *s) {
1822     return !Dep___eq__($self, s);
1823   }
1824 #if defined(SWIGPERL)
1825   %rename("str") __str__;
1826 #endif
1827   const char *__str__() {
1828     return pool_dep2str($self->pool, $self->id);
1829   }
1830   %newobject __repr__;
1831   const char *__repr__() {
1832     char buf[20];
1833     sprintf(buf, "<Id #%d ", $self->id);
1834     return solv_dupjoin(buf, pool_dep2str($self->pool, $self->id), ">");
1835   }
1836 }
1837
1838 %extend XSolvable {
1839   XSolvable(Pool *pool, Id id) {
1840     XSolvable *s;
1841     if (!id || id >= pool->nsolvables)
1842       return 0;
1843     s = solv_calloc(1, sizeof(*s));
1844     s->pool = pool;
1845     s->id = id;
1846     return s;
1847   }
1848   const char *str() {
1849     return pool_solvid2str($self->pool, $self->id);
1850   }
1851   const char *lookup_str(Id keyname) {
1852     return pool_lookup_str($self->pool, $self->id, keyname);
1853   }
1854   Id lookup_id(Id keyname) {
1855     return pool_lookup_id($self->pool, $self->id, keyname);
1856   }
1857   unsigned long long lookup_num(Id keyname, unsigned long long notfound = 0) {
1858     return pool_lookup_num($self->pool, $self->id, keyname, notfound);
1859   }
1860   bool lookup_void(Id keyname) {
1861     return pool_lookup_void($self->pool, $self->id, keyname);
1862   }
1863   %newobject lookup_checksum;
1864   Chksum *lookup_checksum(Id keyname) {
1865     Id type = 0;
1866     const unsigned char *b = pool_lookup_bin_checksum($self->pool, $self->id, keyname, &type);
1867     return solv_chksum_create_from_bin(type, b);
1868   }
1869   Queue lookup_idarray(Id keyname, Id marker = -1) {
1870     Solvable *s = $self->pool->solvables + $self->id;
1871     Queue r;
1872     queue_init(&r);
1873     if (marker == -1 || marker == 1) {
1874       if (keyname == SOLVABLE_PROVIDES)
1875         marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
1876       else if (keyname == SOLVABLE_REQUIRES)
1877         marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
1878       else
1879         marker = 0;
1880     }
1881     solvable_lookup_deparray(s, keyname, &r, marker);
1882     return r;
1883   }
1884   %typemap(out) Queue lookup_deparray Queue2Array(Dep *, 1, new_Dep(arg1->pool, id));
1885   %newobject lookup_deparray;
1886   Queue lookup_deparray(Id keyname, Id marker = -1) {
1887     Solvable *s = $self->pool->solvables + $self->id;
1888     Queue r;
1889     queue_init(&r);
1890     if (marker == -1 || marker == 1) {
1891       if (keyname == SOLVABLE_PROVIDES)
1892         marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
1893       else if (keyname == SOLVABLE_REQUIRES)
1894         marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
1895       else
1896         marker = 0;
1897     }
1898     solvable_lookup_deparray(s, keyname, &r, marker);
1899     return r;
1900   }
1901   const char *lookup_location(unsigned int *OUTPUT) {
1902     return solvable_lookup_location($self->pool->solvables + $self->id, OUTPUT);
1903   }
1904 #ifdef SWIGRUBY
1905   %rename("installable?") installable;
1906 #endif
1907   bool installable() {
1908     return pool_installable($self->pool, pool_id2solvable($self->pool, $self->id));
1909   }
1910 #ifdef SWIGRUBY
1911   %rename("isinstalled?") isinstalled;
1912 #endif
1913   bool isinstalled() {
1914     Pool *pool = $self->pool;
1915     return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed;
1916   }
1917
1918   const char *name;
1919   %{
1920     SWIGINTERN void XSolvable_name_set(XSolvable *xs, const char *name) {
1921       Pool *pool = xs->pool;
1922       pool->solvables[xs->id].name = pool_str2id(pool, name, 1);
1923     }
1924     SWIGINTERN const char *XSolvable_name_get(XSolvable *xs) {
1925       Pool *pool = xs->pool;
1926       return pool_id2str(pool, pool->solvables[xs->id].name);
1927     }
1928   %}
1929   Id nameid;
1930   %{
1931     SWIGINTERN void XSolvable_nameid_set(XSolvable *xs, Id nameid) {
1932       xs->pool->solvables[xs->id].name = nameid;
1933     }
1934     SWIGINTERN Id XSolvable_nameid_get(XSolvable *xs) {
1935       return xs->pool->solvables[xs->id].name;
1936     }
1937   %}
1938   const char *evr;
1939   %{
1940     SWIGINTERN void XSolvable_evr_set(XSolvable *xs, const char *evr) {
1941       Pool *pool = xs->pool;
1942       pool->solvables[xs->id].evr = pool_str2id(pool, evr, 1);
1943     }
1944     SWIGINTERN const char *XSolvable_evr_get(XSolvable *xs) {
1945       Pool *pool = xs->pool;
1946       return pool_id2str(pool, pool->solvables[xs->id].evr);
1947     }
1948   %}
1949   Id evrid;
1950   %{
1951     SWIGINTERN void XSolvable_evrid_set(XSolvable *xs, Id evrid) {
1952       xs->pool->solvables[xs->id].evr = evrid;
1953     }
1954     SWIGINTERN Id XSolvable_evrid_get(XSolvable *xs) {
1955       return xs->pool->solvables[xs->id].evr;
1956     }
1957   %}
1958   const char *arch;
1959   %{
1960     SWIGINTERN void XSolvable_arch_set(XSolvable *xs, const char *arch) {
1961       Pool *pool = xs->pool;
1962       pool->solvables[xs->id].arch = pool_str2id(pool, arch, 1);
1963     }
1964     SWIGINTERN const char *XSolvable_arch_get(XSolvable *xs) {
1965       Pool *pool = xs->pool;
1966       return pool_id2str(pool, pool->solvables[xs->id].arch);
1967     }
1968   %}
1969   Id archid;
1970   %{
1971     SWIGINTERN void XSolvable_archid_set(XSolvable *xs, Id archid) {
1972       xs->pool->solvables[xs->id].arch = archid;
1973     }
1974     SWIGINTERN Id XSolvable_archid_get(XSolvable *xs) {
1975       return xs->pool->solvables[xs->id].arch;
1976     }
1977   %}
1978   const char *vendor;
1979   %{
1980     SWIGINTERN void XSolvable_vendor_set(XSolvable *xs, const char *vendor) {
1981       Pool *pool = xs->pool;
1982       pool->solvables[xs->id].vendor = pool_str2id(pool, vendor, 1);
1983     }
1984     SWIGINTERN const char *XSolvable_vendor_get(XSolvable *xs) {
1985       Pool *pool = xs->pool;
1986       return pool_id2str(pool, pool->solvables[xs->id].vendor);
1987     }
1988   %}
1989   Id vendorid;
1990   %{
1991     SWIGINTERN void XSolvable_vendorid_set(XSolvable *xs, Id vendorid) {
1992       xs->pool->solvables[xs->id].vendor = vendorid;
1993     }
1994     SWIGINTERN Id XSolvable_vendorid_get(XSolvable *xs) {
1995       return xs->pool->solvables[xs->id].vendor;
1996     }
1997   %}
1998   Repo * const repo;
1999   %{
2000     SWIGINTERN Repo *XSolvable_repo_get(XSolvable *xs) {
2001       return xs->pool->solvables[xs->id].repo;
2002     }
2003   %}
2004
2005   void add_provides(Dep *dep, Id marker = -1) {
2006     Solvable *s = $self->pool->solvables + $self->id;
2007     if (marker == -1 || marker == 1)
2008       marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
2009     s->provides = repo_addid_dep(s->repo, s->provides, dep->id, marker);
2010   }
2011   void add_providesid(Id id, Id marker = -1) {
2012     Solvable *s = $self->pool->solvables + $self->id;
2013     if (marker == -1 || marker == 1)
2014       marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
2015     s->provides = repo_addid_dep(s->repo, s->provides, id, marker);
2016   }
2017   void add_obsoletes(Dep *dep) {
2018     Solvable *s = $self->pool->solvables + $self->id;
2019     s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, dep->id, 0);
2020   }
2021   void add_obsoletesid(Id id) {
2022     Solvable *s = $self->pool->solvables + $self->id;
2023     s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, id, 0);
2024   }
2025   void add_conflicts(Dep *dep) {
2026     Solvable *s = $self->pool->solvables + $self->id;
2027     s->conflicts = repo_addid_dep(s->repo, s->conflicts, dep->id, 0);
2028   }
2029   void add_conflictsid(Id id) {
2030     Solvable *s = $self->pool->solvables + $self->id;
2031     s->conflicts = repo_addid_dep(s->repo, s->conflicts, id, 0);
2032   }
2033   void add_requires(Dep *dep, Id marker = -1) {
2034     Solvable *s = $self->pool->solvables + $self->id;
2035     if (marker == -1 || marker == 1)
2036       marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
2037     s->requires = repo_addid_dep(s->repo, s->requires, dep->id, marker);
2038   }
2039   void add_requiresid(Id id, Id marker = -1) {
2040     Solvable *s = $self->pool->solvables + $self->id;
2041     if (marker == -1 || marker == 1)
2042       marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
2043     s->requires = repo_addid_dep(s->repo, s->requires, id, marker);
2044   }
2045   void add_recommends(Dep *dep) {
2046     Solvable *s = $self->pool->solvables + $self->id;
2047     s->recommends = repo_addid_dep(s->repo, s->recommends, dep->id, 0);
2048   }
2049   void add_recommendsid(Id id) {
2050     Solvable *s = $self->pool->solvables + $self->id;
2051     s->recommends = repo_addid_dep(s->repo, s->recommends, id, 0);
2052   }
2053   void add_suggests(Dep *dep) {
2054     Solvable *s = $self->pool->solvables + $self->id;
2055     s->suggests = repo_addid_dep(s->repo, s->suggests, dep->id, 0);
2056   }
2057   void add_suggestsid(Id id) {
2058     Solvable *s = $self->pool->solvables + $self->id;
2059     s->suggests = repo_addid_dep(s->repo, s->suggests, id, 0);
2060   }
2061   void add_supplements(Dep *dep) {
2062     Solvable *s = $self->pool->solvables + $self->id;
2063     s->supplements = repo_addid_dep(s->repo, s->supplements, dep->id, 0);
2064   }
2065   void add_supplementsid(Id id) {
2066     Solvable *s = $self->pool->solvables + $self->id;
2067     s->supplements = repo_addid_dep(s->repo, s->supplements, id, 0);
2068   }
2069   void add_enhances(Dep *dep) {
2070     Solvable *s = $self->pool->solvables + $self->id;
2071     s->enhances = repo_addid_dep(s->repo, s->enhances, dep->id, 0);
2072   }
2073   void add_enhancesid(Id id) {
2074     Solvable *s = $self->pool->solvables + $self->id;
2075     s->enhances = repo_addid_dep(s->repo, s->enhances, id, 0);
2076   }
2077
2078   bool __eq__(XSolvable *s) {
2079     return $self->pool == s->pool && $self->id == s->id;
2080   }
2081   bool __ne__(XSolvable *s) {
2082     return !XSolvable___eq__($self, s);
2083   }
2084 #if defined(SWIGPERL)
2085   %rename("str") __str__;
2086 #endif
2087   const char *__str__() {
2088     return pool_solvid2str($self->pool, $self->id);
2089   }
2090   %newobject __repr__;
2091   const char *__repr__() {
2092     char buf[20];
2093     sprintf(buf, "<Solvable #%d ", $self->id);
2094     return solv_dupjoin(buf, pool_solvid2str($self->pool, $self->id), ">");
2095   }
2096 }
2097
2098 %extend Problem {
2099   Problem(Solver *solv, Id id) {
2100     Problem *p;
2101     p = solv_calloc(1, sizeof(*p));
2102     p->solv = solv;
2103     p->id = id;
2104     return p;
2105   }
2106   %newobject findproblemrule;
2107   XRule *findproblemrule() {
2108     Id r = solver_findproblemrule($self->solv, $self->id);
2109     return new_XRule($self->solv, r);
2110   }
2111   %newobject findallproblemrules;
2112   %typemap(out) Queue findallproblemrules Queue2Array(XRule *, 1, new_XRule(arg1->solv, id));
2113   Queue findallproblemrules(int unfiltered=0) {
2114     Solver *solv = $self->solv;
2115     Id probr;
2116     int i, j;
2117     Queue q;
2118     queue_init(&q);
2119     solver_findallproblemrules(solv, $self->id, &q);
2120     if (!unfiltered)
2121       {
2122         for (i = j = 0; i < q.count; i++)
2123           {
2124             SolverRuleinfo rclass;
2125             probr = q.elements[i];
2126             rclass = solver_ruleclass(solv, probr);
2127             if (rclass == SOLVER_RULE_UPDATE || rclass == SOLVER_RULE_JOB)
2128               continue;
2129             q.elements[j++] = probr;
2130           }
2131         if (j)
2132           queue_truncate(&q, j);
2133       }
2134     return q;
2135   }
2136   int solution_count() {
2137     return solver_solution_count($self->solv, $self->id);
2138   }
2139   %newobject solutions;
2140   %typemap(out) Queue solutions Queue2Array(Solution *, 1, new_Solution(arg1, id));
2141   Queue solutions() {
2142     Queue q;
2143     int i, cnt;
2144     queue_init(&q);
2145     cnt = solver_solution_count($self->solv, $self->id);
2146     for (i = 1; i <= cnt; i++)
2147       queue_push(&q, i);
2148     return q;
2149   }
2150 }
2151
2152 %extend Solution {
2153   Solution(Problem *p, Id id) {
2154     Solution *s;
2155     s = solv_calloc(1, sizeof(*s));
2156     s->solv = p->solv;
2157     s->problemid = p->id;
2158     s->id = id;
2159     return s;
2160   }
2161   int element_count() {
2162     return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
2163   }
2164
2165   %newobject elements;
2166   %typemap(out) Queue elements Queue2Array(Solutionelement *, 4, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2], idp[3]));
2167   Queue elements(bool expandreplaces=0) {
2168     Queue q;
2169     int i, cnt;
2170     queue_init(&q);
2171     cnt = solver_solutionelement_count($self->solv, $self->problemid, $self->id);
2172     for (i = 1; i <= cnt; i++)
2173       {
2174         Id p, rp, type;
2175         solver_next_solutionelement($self->solv, $self->problemid, $self->id, i - 1, &p, &rp);
2176         if (p > 0) {
2177           type = rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE;
2178         } else {
2179           type = p;
2180           p = rp;
2181           rp = 0;
2182         }
2183         if (type == SOLVER_SOLUTION_REPLACE && expandreplaces) {
2184           int illegal = policy_is_illegal(self->solv, self->solv->pool->solvables + p, self->solv->pool->solvables + rp, 0);
2185           if (illegal) {
2186             if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) {
2187               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
2188               queue_push2(&q, p, rp);
2189             }
2190             if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) {
2191               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
2192               queue_push2(&q, p, rp);
2193             }
2194             if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) {
2195               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
2196               queue_push2(&q, p, rp);
2197             }
2198             continue;
2199           }
2200         }
2201         queue_push2(&q, i, type);
2202         queue_push2(&q, p, rp);
2203       }
2204     return q;
2205   }
2206 }
2207
2208 %extend Solutionelement {
2209   Solutionelement(Solver *solv, Id problemid, Id solutionid, Id id, Id type, Id p, Id rp) {
2210     Solutionelement *e;
2211     e = solv_calloc(1, sizeof(*e));
2212     e->solv = solv;
2213     e->problemid = problemid;
2214     e->solutionid = id;
2215     e->id = id;
2216     e->type = type;
2217     e->p = p;
2218     e->rp = rp;
2219     return e;
2220   }
2221   const char *str() {
2222     Id p = $self->type;
2223     Id rp = $self->p;
2224     if (p == SOLVER_SOLUTION_ERASE)
2225       {
2226         p = rp;
2227         rp = 0;
2228       }
2229     else if (p == SOLVER_SOLUTION_REPLACE)
2230       {
2231         p = rp;
2232         rp = $self->rp;
2233       }
2234     else if (p == SOLVER_SOLUTION_REPLACE_DOWNGRADE)
2235       return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_DOWNGRADE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
2236     else if (p == SOLVER_SOLUTION_REPLACE_ARCHCHANGE)
2237       return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_ARCHCHANGE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
2238     else if (p == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
2239       return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_VENDORCHANGE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
2240     return solver_solutionelement2str($self->solv, p, rp);
2241   }
2242   %newobject replaceelements;
2243   %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, arg1->id, id, arg1->p, arg1->rp));
2244   Queue replaceelements() {
2245     Queue q;
2246     int illegal;
2247
2248     queue_init(&q);
2249     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
2250       illegal = 0;
2251     else
2252       illegal = policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
2253     if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
2254       queue_push(&q, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
2255     if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
2256       queue_push(&q, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
2257     if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
2258       queue_push(&q, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
2259     if (!q.count)
2260       queue_push(&q, $self->type);
2261     return q;
2262   }
2263   int illegalreplace() {
2264     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
2265       return 0;
2266     return policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
2267   }
2268   %newobject solvable;
2269   XSolvable * const solvable;
2270   %newobject replacement;
2271   XSolvable * const replacement;
2272   int const jobidx;
2273   %{
2274     SWIGINTERN XSolvable *Solutionelement_solvable_get(Solutionelement *e) {
2275       return new_XSolvable(e->solv->pool, e->p);
2276     }
2277     SWIGINTERN XSolvable *Solutionelement_replacement_get(Solutionelement *e) {
2278       return new_XSolvable(e->solv->pool, e->rp);
2279     }
2280     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
2281       if (e->type != SOLVER_SOLUTION_JOB)
2282         return -1;
2283       return (e->p - 1) / 2;
2284     }
2285   %}
2286   %newobject Job;
2287   Job *Job() {
2288     Id extraflags = solver_solutionelement_extrajobflags($self->solv, $self->problemid, $self->solutionid);
2289     if ($self->type == SOLVER_SOLUTION_JOB)
2290       return new_Job($self->solv->pool, SOLVER_NOOP, 0);
2291     if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE)
2292       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->p);
2293     if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
2294       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->rp);
2295     if ($self->type == SOLVER_SOLUTION_ERASE)
2296       return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE|extraflags, $self->p);
2297     return 0;
2298   }
2299 }
2300
2301 %extend Solver {
2302   static const int SOLVER_RULE_UNKNOWN = SOLVER_RULE_UNKNOWN;
2303   static const int SOLVER_RULE_RPM = SOLVER_RULE_RPM;
2304   static const int SOLVER_RULE_RPM_NOT_INSTALLABLE = SOLVER_RULE_RPM_NOT_INSTALLABLE;
2305   static const int SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP = SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP;
2306   static const int SOLVER_RULE_RPM_PACKAGE_REQUIRES = SOLVER_RULE_RPM_PACKAGE_REQUIRES;
2307   static const int SOLVER_RULE_RPM_SELF_CONFLICT = SOLVER_RULE_RPM_SELF_CONFLICT;
2308   static const int SOLVER_RULE_RPM_PACKAGE_CONFLICT = SOLVER_RULE_RPM_PACKAGE_CONFLICT;
2309   static const int SOLVER_RULE_RPM_SAME_NAME = SOLVER_RULE_RPM_SAME_NAME;
2310   static const int SOLVER_RULE_RPM_PACKAGE_OBSOLETES = SOLVER_RULE_RPM_PACKAGE_OBSOLETES;
2311   static const int SOLVER_RULE_RPM_IMPLICIT_OBSOLETES = SOLVER_RULE_RPM_IMPLICIT_OBSOLETES;
2312   static const int SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES = SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES;
2313   static const int SOLVER_RULE_UPDATE = SOLVER_RULE_UPDATE;
2314   static const int SOLVER_RULE_FEATURE = SOLVER_RULE_FEATURE;
2315   static const int SOLVER_RULE_JOB = SOLVER_RULE_JOB;
2316   static const int SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP = SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP;
2317   static const int SOLVER_RULE_DISTUPGRADE = SOLVER_RULE_DISTUPGRADE;
2318   static const int SOLVER_RULE_INFARCH = SOLVER_RULE_INFARCH;
2319   static const int SOLVER_RULE_CHOICE = SOLVER_RULE_CHOICE;
2320   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
2321
2322   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
2323   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
2324   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
2325   static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE;
2326   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
2327   static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE;
2328   static const int SOLVER_SOLUTION_REPLACE_ARCHCHANGE = SOLVER_SOLUTION_REPLACE_ARCHCHANGE;
2329   static const int SOLVER_SOLUTION_REPLACE_VENDORCHANGE = SOLVER_SOLUTION_REPLACE_VENDORCHANGE;
2330
2331   static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE;
2332   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
2333   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
2334
2335   static const int SOLVER_FLAG_ALLOW_DOWNGRADE = SOLVER_FLAG_ALLOW_DOWNGRADE;
2336   static const int SOLVER_FLAG_ALLOW_ARCHCHANGE = SOLVER_FLAG_ALLOW_ARCHCHANGE;
2337   static const int SOLVER_FLAG_ALLOW_VENDORCHANGE = SOLVER_FLAG_ALLOW_VENDORCHANGE;
2338   static const int SOLVER_FLAG_ALLOW_UNINSTALL = SOLVER_FLAG_ALLOW_UNINSTALL;
2339   static const int SOLVER_FLAG_NO_UPDATEPROVIDE = SOLVER_FLAG_NO_UPDATEPROVIDE;
2340   static const int SOLVER_FLAG_SPLITPROVIDES = SOLVER_FLAG_SPLITPROVIDES;
2341   static const int SOLVER_FLAG_IGNORE_RECOMMENDED = SOLVER_FLAG_IGNORE_RECOMMENDED;
2342   static const int SOLVER_FLAG_ADD_ALREADY_RECOMMENDED = SOLVER_FLAG_ADD_ALREADY_RECOMMENDED;
2343   static const int SOLVER_FLAG_NO_INFARCHCHECK = SOLVER_FLAG_NO_INFARCHCHECK;
2344
2345   ~Solver() {
2346     solver_free($self);
2347   }
2348
2349   int set_flag(int flag, int value) {
2350     return solver_set_flag($self, flag, value);
2351   }
2352   int get_flag(int flag) {
2353     return solver_get_flag($self, flag);
2354   }
2355 #if defined(SWIGPYTHON)
2356   %pythoncode {
2357     def solve(self, jobs):
2358       j = []
2359       for job in jobs: j += [job.how, job.what]
2360       return self.solve_helper(j)
2361   }
2362 #endif
2363 #if defined(SWIGPERL)
2364   %perlcode {
2365     sub solv::Solver::solve {
2366       my ($self, $jobs) = @_;
2367       my @j = map {($_->{'how'}, $_->{'what'})} @$jobs;
2368       return $self->solve_helper(\@j);
2369     }
2370   }
2371 #endif
2372 #if defined(SWIGRUBY)
2373 %init %{
2374 rb_eval_string(
2375     "class Solv::Solver\n"
2376     "  def solve(jobs)\n"
2377     "    jl = []\n"
2378     "    jobs.each do |j| ; jl << j.how << j.what ; end\n"
2379     "    solve_helper(jl)\n"
2380     "  end\n"
2381     "end\n"
2382   );
2383 %}
2384 #endif
2385   %typemap(out) Queue solve_helper Queue2Array(Problem *, 1, new_Problem(arg1, id));
2386   %newobject solve_helper;
2387   Queue solve_helper(Queue jobs) {
2388     Queue q;
2389     int i, cnt;
2390     queue_init(&q);
2391     solver_solve($self, &jobs);
2392     cnt = solver_problem_count($self);
2393     for (i = 1; i <= cnt; i++)
2394       queue_push(&q, i);
2395     return q;
2396   }
2397   %newobject transaction;
2398   Transaction *transaction() {
2399     return solver_create_transaction($self);
2400   }
2401 }
2402
2403 %extend Transaction {
2404   static const int SOLVER_TRANSACTION_IGNORE = SOLVER_TRANSACTION_IGNORE;
2405   static const int SOLVER_TRANSACTION_ERASE = SOLVER_TRANSACTION_ERASE;
2406   static const int SOLVER_TRANSACTION_REINSTALLED = SOLVER_TRANSACTION_REINSTALLED;
2407   static const int SOLVER_TRANSACTION_DOWNGRADED = SOLVER_TRANSACTION_DOWNGRADED;
2408   static const int SOLVER_TRANSACTION_CHANGED = SOLVER_TRANSACTION_CHANGED;
2409   static const int SOLVER_TRANSACTION_UPGRADED = SOLVER_TRANSACTION_UPGRADED;
2410   static const int SOLVER_TRANSACTION_OBSOLETED = SOLVER_TRANSACTION_OBSOLETED;
2411   static const int SOLVER_TRANSACTION_INSTALL = SOLVER_TRANSACTION_INSTALL;
2412   static const int SOLVER_TRANSACTION_REINSTALL = SOLVER_TRANSACTION_REINSTALL;
2413   static const int SOLVER_TRANSACTION_DOWNGRADE = SOLVER_TRANSACTION_DOWNGRADE;
2414   static const int SOLVER_TRANSACTION_CHANGE = SOLVER_TRANSACTION_CHANGE;
2415   static const int SOLVER_TRANSACTION_UPGRADE = SOLVER_TRANSACTION_UPGRADE;
2416   static const int SOLVER_TRANSACTION_OBSOLETES = SOLVER_TRANSACTION_OBSOLETES;
2417   static const int SOLVER_TRANSACTION_MULTIINSTALL = SOLVER_TRANSACTION_MULTIINSTALL;
2418   static const int SOLVER_TRANSACTION_MULTIREINSTALL = SOLVER_TRANSACTION_MULTIREINSTALL;
2419   static const int SOLVER_TRANSACTION_MAXTYPE = SOLVER_TRANSACTION_MAXTYPE;
2420   static const int SOLVER_TRANSACTION_SHOW_ACTIVE = SOLVER_TRANSACTION_SHOW_ACTIVE;
2421   static const int SOLVER_TRANSACTION_SHOW_ALL = SOLVER_TRANSACTION_SHOW_ALL;
2422   static const int SOLVER_TRANSACTION_SHOW_OBSOLETES = SOLVER_TRANSACTION_SHOW_OBSOLETES;
2423   static const int SOLVER_TRANSACTION_SHOW_MULTIINSTALL = SOLVER_TRANSACTION_SHOW_MULTIINSTALL;
2424   static const int SOLVER_TRANSACTION_CHANGE_IS_REINSTALL = SOLVER_TRANSACTION_CHANGE_IS_REINSTALL;
2425   static const int SOLVER_TRANSACTION_MERGE_VENDORCHANGES = SOLVER_TRANSACTION_MERGE_VENDORCHANGES;
2426   static const int SOLVER_TRANSACTION_MERGE_ARCHCHANGES = SOLVER_TRANSACTION_MERGE_ARCHCHANGES;
2427   static const int SOLVER_TRANSACTION_RPM_ONLY = SOLVER_TRANSACTION_RPM_ONLY;
2428   static const int SOLVER_TRANSACTION_ARCHCHANGE = SOLVER_TRANSACTION_ARCHCHANGE;
2429   static const int SOLVER_TRANSACTION_VENDORCHANGE = SOLVER_TRANSACTION_VENDORCHANGE;
2430   static const int SOLVER_TRANSACTION_KEEP_ORDERDATA = SOLVER_TRANSACTION_KEEP_ORDERDATA;
2431   ~Transaction() {
2432     transaction_free($self);
2433   }
2434 #ifdef SWIGRUBY
2435   %rename("isempty?") isempty;
2436 #endif
2437   bool isempty() {
2438     return $self->steps.count == 0;
2439   }
2440
2441   %newobject othersolvable;
2442   XSolvable *othersolvable(XSolvable *s) {
2443     Id op = transaction_obs_pkg($self, s->id);
2444     return new_XSolvable($self->pool, op);
2445   }
2446
2447   %newobject allothersolvables;
2448   %typemap(out) Queue allothersolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2449   Queue allothersolvables(XSolvable *s) {
2450     Queue q;
2451     queue_init(&q);
2452     transaction_all_obs_pkgs($self, s->id, &q);
2453     return q;
2454   }
2455
2456   %typemap(out) Queue classify Queue2Array(TransactionClass *, 4, new_TransactionClass(arg1, arg2, id, idp[1], idp[2], idp[3]));
2457   %newobject classify;
2458   Queue classify(int mode = 0) {
2459     Queue q;
2460     queue_init(&q);
2461     transaction_classify($self, mode, &q);
2462     return q;
2463   }
2464
2465   %typemap(out) Queue newpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2466   %newobject newpackages;
2467   Queue newpackages() {
2468     Queue q;
2469     int cut;
2470     queue_init(&q);
2471     cut = transaction_installedresult(self, &q);
2472     queue_truncate(&q, cut);
2473     return q;
2474   }
2475
2476   %typemap(out) Queue keptpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2477   %newobject keptpackages;
2478   Queue keptpackages() {
2479     Queue q;
2480     int cut;
2481     queue_init(&q);
2482     cut = transaction_installedresult(self, &q);
2483     if (cut)
2484       queue_deleten(&q, 0, cut);
2485     return q;
2486   }
2487
2488   %typemap(out) Queue steps Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2489   %newobject steps ;
2490   Queue steps() {
2491     Queue q;
2492     queue_init_clone(&q, &$self->steps);
2493     return q;
2494   }
2495
2496   int steptype(XSolvable *s, int mode) {
2497     return transaction_type($self, s->id, mode);
2498   }
2499   int calc_installsizechange() {
2500     return transaction_calc_installsizechange($self);
2501   }
2502   void order(int flags) {
2503     transaction_order($self, flags);
2504   }
2505 }
2506
2507 %extend TransactionClass {
2508   TransactionClass(Transaction *trans, int mode, Id type, int count, Id fromid, Id toid) {
2509     TransactionClass *cl = solv_calloc(1, sizeof(*cl));
2510     cl->transaction = trans;
2511     cl->mode = mode;
2512     cl->type = type;
2513     cl->count = count;
2514     cl->fromid = fromid;
2515     cl->toid = toid;
2516     return cl;
2517   }
2518   %newobject solvables;
2519   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->transaction->pool, id));
2520   Queue solvables() {
2521     Queue q;
2522     queue_init(&q);
2523     transaction_classify_pkgs($self->transaction, $self->mode, $self->type, $self->fromid, $self->toid, &q);
2524     return q;
2525   }
2526 }
2527
2528 %extend XRule {
2529   XRule(Solver *solv, Id id) {
2530     if (!id)
2531       return 0;
2532     XRule *xr = solv_calloc(1, sizeof(*xr));
2533     xr->solv = solv;
2534     xr->id = id;
2535     return xr;
2536   }
2537   Ruleinfo *info() {
2538     Id type, source, target, dep;
2539     type =  solver_ruleinfo($self->solv, $self->id, &source, &target, &dep);
2540     return new_Ruleinfo($self, type, source, target, dep);
2541   }
2542   %typemap(out) Queue allinfos Queue2Array(Ruleinfo *, 4, new_Ruleinfo(arg1, id, idp[1], idp[2], idp[3]));
2543   %newobject allinfos;
2544   Queue allinfos() {
2545     Queue q;
2546     queue_init(&q);
2547     solver_allruleinfos($self->solv, $self->id, &q);
2548     return q;
2549   }
2550
2551   bool __eq__(XRule *xr) {
2552     return $self->solv == xr->solv && $self->id == xr->id;
2553   }
2554   bool __ne__(XRule *xr) {
2555     return !XRule___eq__($self, xr);
2556   }
2557   %newobject __repr__;
2558   const char *__repr__() {
2559     char buf[20];
2560     sprintf(buf, "<Rule #%d>", $self->id);
2561     return solv_strdup(buf);
2562   }
2563 }
2564
2565 %extend Ruleinfo {
2566   Ruleinfo(XRule *r, Id type, Id source, Id target, Id dep) {
2567     Ruleinfo *ri = solv_calloc(1, sizeof(*ri));
2568     ri->solv = r->solv;
2569     ri->rid = r->id;
2570     ri->type = type;
2571     ri->source = source;
2572     ri->target = target;
2573     ri->dep = dep;
2574     return ri;
2575   }
2576   XSolvable * const solvable;
2577   XSolvable * const othersolvable;
2578   %{
2579     SWIGINTERN XSolvable *Ruleinfo_solvable_get(Ruleinfo *ri) {
2580       return new_XSolvable(ri->solv->pool, ri->source);
2581     }
2582     SWIGINTERN XSolvable *Ruleinfo_othersolvable_get(Ruleinfo *ri) {
2583       return new_XSolvable(ri->solv->pool, ri->target);
2584     }
2585   %}
2586   const char *problemstr() {
2587     return solver_problemruleinfo2str($self->solv, $self->type, $self->source, $self->target, $self->dep);
2588   }
2589 }
2590
2591 %extend XRepodata {
2592   XRepodata(Repo *repo, Id id) {
2593     XRepodata *xr = solv_calloc(1, sizeof(*xr));
2594     xr->repo = repo;
2595     xr->id = id;
2596     return xr;
2597   }
2598   Id new_handle() {
2599     return repodata_new_handle(repo_id2repodata($self->repo, $self->id));
2600   }
2601   void set_id(Id solvid, Id keyname, Id id) {
2602     repodata_set_id(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
2603   }
2604   void set_str(Id solvid, Id keyname, const char *str) {
2605     repodata_set_str(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
2606   }
2607   void set_poolstr(Id solvid, Id keyname, const char *str) {
2608     repodata_set_poolstr(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
2609   }
2610   void add_idarray(Id solvid, Id keyname, Id id) {
2611     repodata_add_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
2612   }
2613   void add_flexarray(Id solvid, Id keyname, Id handle) {
2614     repodata_add_flexarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, handle);
2615   }
2616   void set_checksum(Id solvid, Id keyname, Chksum *chksum) {
2617     const unsigned char *buf = solv_chksum_get(chksum, 0);
2618     if (buf)
2619       repodata_set_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, solv_chksum_get_type(chksum), buf);
2620   }
2621   const char *lookup_str(Id solvid, Id keyname) {
2622     return repodata_lookup_str(repo_id2repodata($self->repo, $self->id), solvid, keyname);
2623   }
2624   Queue lookup_idarray(Id solvid, Id keyname) {
2625     Queue r;
2626     queue_init(&r);
2627     repodata_lookup_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, &r);
2628     return r;
2629   }
2630   %newobject lookup_checksum;
2631   Chksum *lookup_checksum(Id solvid, Id keyname) {
2632     Id type = 0;
2633     const unsigned char *b = repodata_lookup_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, &type);
2634     return solv_chksum_create_from_bin(type, b);
2635   }
2636   void internalize() {
2637     repodata_internalize(repo_id2repodata($self->repo, $self->id));
2638   }
2639   void create_stubs() {
2640     repodata_create_stubs(repo_id2repodata($self->repo, $self->id));
2641   }
2642   void write(FILE *fp) {
2643     repodata_write(repo_id2repodata($self->repo, $self->id), fp);
2644   }
2645   bool add_solv(FILE *fp, int flags = 0) {
2646     Repodata *data = repo_id2repodata($self->repo, $self->id);
2647     int r, oldstate = data->state;
2648     data->state = REPODATA_LOADING;
2649     r = repo_add_solv(data->repo, fp, flags | REPO_USE_LOADING);
2650     if (r || data->state == REPODATA_LOADING)
2651       data->state = oldstate;
2652     return r;
2653   }
2654   void extend_to_repo() {
2655     Repodata *data = repo_id2repodata($self->repo, $self->id);
2656     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
2657   }
2658   bool __eq__(XRepodata *xr) {
2659     return $self->repo == xr->repo && $self->id == xr->id;
2660   }
2661   bool __ne__(XRepodata *xr) {
2662     return !XRepodata___eq__($self, xr);
2663   }
2664   %newobject __repr__;
2665   const char *__repr__() {
2666     char buf[20];
2667     sprintf(buf, "<Repodata #%d>", $self->id);
2668     return solv_strdup(buf);
2669   }
2670 }
2671