- fix build on 64bit and 11.3
[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($input)->len;
147   i = 0;
148   o = RARRAY($input)->ptr;
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;
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 <stdio.h>
335 #include <sys/stat.h>
336 #include <sys/types.h>
337 #include <unistd.h>
338
339 #include "pool.h"
340 #include "poolarch.h"
341 #include "solver.h"
342 #include "policy.h"
343 #include "solverdebug.h"
344 #include "repo_solv.h"
345 #include "chksum.h"
346
347 #ifndef DEBIAN
348 #include "repo_rpmdb.h"
349 #endif
350 #include "repo_deb.h"
351 #include "repo_rpmmd.h"
352 #include "repo_write.h"
353 #include "repo_products.h"
354 #include "repo_susetags.h"
355 #include "repo_updateinfoxml.h"
356 #include "repo_deltainfoxml.h"
357 #include "repo_repomdxml.h"
358 #include "repo_content.h"
359 #include "solv_xfopen.h"
360
361 #define true 1
362 #define false 1
363
364 #define SOLVER_SOLUTION_ERASE                   -100
365 #define SOLVER_SOLUTION_REPLACE                 -101
366 #define SOLVER_SOLUTION_REPLACE_DOWNGRADE       -102
367 #define SOLVER_SOLUTION_REPLACE_ARCHCHANGE      -103
368 #define SOLVER_SOLUTION_REPLACE_VENDORCHANGE    -104
369
370 typedef struct chksum Chksum;
371 typedef int bool;
372 typedef void *AppObjectPtr;
373
374 typedef struct {
375   Pool *pool;
376   Id id;
377 } Dep;
378
379 typedef struct {
380   Pool *pool;
381   Id id;
382 } XSolvable;
383
384 typedef struct {
385   Solver *solv;
386   Id id;
387 } XRule;
388
389 typedef struct {
390   Repo *repo;
391   Id id;
392 } XRepodata;
393
394 typedef struct {
395   Pool *pool;
396   Id id;
397 } Pool_solvable_iterator;
398
399 typedef struct {
400   Pool *pool;
401   Id id;
402 } Pool_repo_iterator;
403
404 typedef struct {
405   Repo *repo;
406   Id id;
407 } Repo_solvable_iterator;
408
409 typedef struct {
410   Pool *pool;
411   int how;
412   Id what;
413 } Job;
414
415 typedef struct {
416   Solver *solv;
417   Id id;
418 } Problem;
419
420 typedef struct {
421   Solver *solv;
422   Id problemid;
423   Id id;
424 } Solution;
425
426 typedef struct {
427   Solver *solv;
428   Id problemid;
429   Id solutionid;
430   Id id;
431
432   Id type;
433   Id p;
434   Id rp;
435 } Solutionelement;
436
437 typedef struct {
438   Solver *solv;
439   Id rid;
440   Id type;
441   Id source;
442   Id target;
443   Id dep;
444 } Ruleinfo;
445
446 typedef struct {
447   Transaction *transaction;
448   int mode;
449   Id type;
450   int count;
451   Id fromid;
452   Id toid;
453 } TransactionClass;
454
455 typedef Dataiterator Datamatch;
456
457 %}
458
459 #ifdef SWIGRUBY
460 %mixin Dataiterator "Enumerable";
461 %mixin Pool_solvable_iterator "Enumerable";
462 %mixin Pool_repo_iterator "Enumerable";
463 %mixin Repo_solvable_iterator "Enumerable";
464 #endif
465
466 typedef int Id;
467
468 %include "knownid.h"
469
470 # from repodata.h
471 %constant Id SOLVID_META;
472 %constant Id SOLVID_POS;
473
474 %constant int REL_EQ;
475 %constant int REL_GT;
476 %constant int REL_LT;
477 %constant int REL_ARCH;
478
479 typedef struct {
480   Pool* const pool;
481   Id const id;
482 } Dep;
483
484 typedef struct {
485   Pool* const pool;
486   Id const id;
487 } XSolvable;
488
489 typedef struct {
490   Solver* const solv;
491   Id const type;
492   Id const dep;
493 } Ruleinfo;
494
495 typedef struct {
496   Solver* const solv;
497   Id const id;
498 } XRule;
499
500 typedef struct {
501   Repo* const repo;
502   Id const id;
503 } XRepodata;
504
505 # put before pool/repo so we can access the constructor
506 %nodefaultdtor Dataiterator;
507 typedef struct {} Dataiterator;
508 typedef struct {} Pool_solvable_iterator;
509 typedef struct {} Pool_repo_iterator;
510 typedef struct {} Repo_solvable_iterator;
511
512 %nodefaultctor Datamatch;
513 %nodefaultdtor Datamatch;
514 typedef struct {
515   Pool * const pool;
516   Repo * const repo;
517   Id const solvid;
518 } Datamatch;
519
520 %nodefaultctor Datapos;
521 typedef struct {
522   Repo * const repo;
523 } Datapos;
524
525 typedef struct {
526   Pool * const pool;
527   int how;
528   Id what;
529 } Job;
530
531 %nodefaultctor Pool;
532 %nodefaultdtor Pool;
533 typedef struct {
534   AppObjectPtr appdata;
535 } Pool;
536
537 %nodefaultctor Repo;
538 %nodefaultdtor Repo;
539 typedef struct _Repo {
540   Pool * const pool;
541   const char * const name;
542   int priority;
543   int subpriority;
544   int const nsolvables;
545   AppObjectPtr appdata;
546 } Repo;
547
548 %nodefaultctor Solver;
549 %nodefaultdtor Solver;
550 typedef struct {
551   Pool * const pool;
552   bool fixsystem;
553   bool allowdowngrade;
554   bool allowarchchange;
555   bool allowvendorchange;
556   bool allowuninstall;
557   bool updatesystem;
558   bool noupdateprovide;
559   bool dosplitprovides;
560   bool dontinstallrecommended;
561   bool ignorealreadyrecommended;
562   bool dontshowinstalledrecommended;
563   bool distupgrade;
564   bool distupgrade_removeunsupported;
565   bool noinfarchcheck;
566 } Solver;
567
568 typedef struct chksum {
569 } Chksum;
570
571 %rename(xfopen) solv_xfopen;
572 %rename(xfopen_fd) solv_xfopen_fd;
573 %rename(xfopen_dup) solv_xfopen_dup;
574 %rename(xfclose) solv_xfclose;
575 %rename(xfileno) solv_xfileno;
576
577 FILE *solv_xfopen(const char *fn, const char *mode = 0);
578 FILE *solv_xfopen_fd(const char *fn, int fd, const char *mode = 0);
579 FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode = 0);
580 int solv_xfclose(FILE *fp);
581 int solv_xfileno(FILE *fp);
582
583 %{
584   SWIGINTERN int solv_xfclose(FILE *fp) {
585     return fclose(fp);
586   }
587   SWIGINTERN int solv_xfileno(FILE *fp) {
588     return fileno(fp);
589   }
590   SWIGINTERN FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode) {
591     fd = dup(fd);
592     return fd == -1 ? 0 : solv_xfopen_fd(fn, fd, mode);
593   }
594 %}
595
596 typedef struct {
597   Solver * const solv;
598   Id const id;
599 } Problem;
600
601 typedef struct {
602   Solver * const solv;
603   Id const problemid;
604   Id const id;
605 } Solution;
606
607 typedef struct {
608   Solver *const solv;
609   Id const problemid;
610   Id const solutionid;
611   Id const id;
612   Id const type;
613 } Solutionelement;
614
615 %nodefaultctor Transaction;
616 %nodefaultdtor Transaction;
617 typedef struct {
618   Pool * const pool;
619 } Transaction;
620
621 typedef struct {
622   Transaction * const transaction;
623   Id const type;
624   Id const fromid;
625   Id const toid;
626   int const count;
627 } TransactionClass;
628
629
630 %extend Job {
631   static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
632   static const Id SOLVER_SOLVABLE_NAME = SOLVER_SOLVABLE_NAME;
633   static const Id SOLVER_SOLVABLE_PROVIDES = SOLVER_SOLVABLE_PROVIDES;
634   static const Id SOLVER_SOLVABLE_ONE_OF = SOLVER_SOLVABLE_ONE_OF;
635   static const Id SOLVER_SOLVABLE_REPO = SOLVER_SOLVABLE_REPO;
636   static const Id SOLVER_SOLVABLE_ALL = SOLVER_SOLVABLE_ALL;
637   static const Id SOLVER_SELECTMASK = SOLVER_SELECTMASK;
638   static const Id SOLVER_NOOP = SOLVER_NOOP;
639   static const Id SOLVER_INSTALL = SOLVER_INSTALL;
640   static const Id SOLVER_ERASE = SOLVER_ERASE;
641   static const Id SOLVER_UPDATE = SOLVER_UPDATE;
642   static const Id SOLVER_WEAKENDEPS = SOLVER_WEAKENDEPS;
643   static const Id SOLVER_NOOBSOLETES = SOLVER_NOOBSOLETES;
644   static const Id SOLVER_LOCK = SOLVER_LOCK;
645   static const Id SOLVER_DISTUPGRADE = SOLVER_DISTUPGRADE;
646   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
647   static const Id SOLVER_DROP_ORPHANED = SOLVER_DROP_ORPHANED;
648   static const Id SOLVER_USERINSTALLED = SOLVER_USERINSTALLED;
649   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
650   static const Id SOLVER_WEAK = SOLVER_WEAK;
651   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
652   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
653   static const Id SOLVER_SETEV = SOLVER_SETEV;
654   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
655   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
656   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
657   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
658   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
659   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
660
661   Job(Pool *pool, int how, Id what) {
662     Job *job = solv_calloc(1, sizeof(*job));
663     job->pool = pool;
664     job->how = how;
665     job->what = what;
666     return job;
667   }
668
669   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
670   %newobject solvables;
671   Queue solvables() {
672     Pool *pool = $self->pool;
673     Id p, pp, how;
674     Queue q;
675     queue_init(&q);
676     how = $self->how & SOLVER_SELECTMASK;
677     FOR_JOB_SELECT(p, pp, how, $self->what)
678       queue_push(&q, p);
679     return q;
680   }
681
682   bool __eq__(Job *j) {
683     return $self->pool == j->pool && $self->how == j->how && $self->what == j->what;
684   }
685   bool __ne__(Job *j) {
686     return !Job___eq__($self, j);
687   }
688 #if defined(SWIGPERL)
689   %rename("str") __str__;
690 #endif
691   const char *__str__() {
692     return pool_job2str($self->pool, $self->how, $self->what, 0);
693   }
694   const char *__repr__() {
695     const char *str = pool_job2str($self->pool, $self->how, $self->what, ~0);
696     return pool_tmpjoin($self->pool, "<Job ", str, ">");
697   }
698 }
699
700 %extend Chksum {
701   Chksum(Id type) {
702     return (Chksum *)solv_chksum_create(type);
703   }
704   Chksum(Id type, const char *hex) {
705     unsigned char buf[64];
706     int l = solv_chksum_len(type);
707     if (!l)
708       return 0;
709     if (solv_hex2bin(&hex, buf, sizeof(buf)) != l || hex[0])
710       return 0;
711     return (Chksum *)solv_chksum_create_from_bin(type, buf);
712   }
713   ~Chksum() {
714     solv_chksum_free($self, 0);
715   }
716   Id const type;
717   %{
718   SWIGINTERN Id Chksum_type_get(Chksum *chksum) {
719     return solv_chksum_get_type(chksum);
720   }
721   %}
722   void add(const char *str) {
723     solv_chksum_add($self, str, strlen((char *)str));
724   }
725   void add_fp(FILE *fp) {
726     char buf[4096];
727     int l;
728     while ((l = fread(buf, 1, sizeof(buf), fp)) > 0)
729       solv_chksum_add($self, buf, l);
730     rewind(fp);         /* convenience */
731   }
732   void add_fd(int fd) {
733     char buf[4096];
734     int l;
735     while ((l = read(fd, buf, sizeof(buf))) > 0)
736       solv_chksum_add($self, buf, l);
737     lseek(fd, 0, 0);    /* convenience */
738   }
739   void add_stat(const char *filename) {
740     struct stat stb;
741     if (stat(filename, &stb))
742       memset(&stb, 0, sizeof(stb));
743     solv_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
744     solv_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
745     solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
746     solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
747   }
748   SWIGCDATA raw() {
749     int l;
750     const unsigned char *b;
751     b = solv_chksum_get($self, &l);
752     return cdata_void((void *)b, l);
753   }
754   %newobject hex;
755   char *hex() {
756     int l;
757     const unsigned char *b;
758     char *ret;
759
760     b = solv_chksum_get($self, &l);
761     ret = solv_malloc(2 * l + 1);
762     solv_bin2hex(b, l, ret);
763     return ret;
764   }
765
766   bool __eq__(Chksum *chk) {
767     int l;
768     const unsigned char *b, *bo;
769     if (!chk)
770       return 0;
771     if (solv_chksum_get_type($self) != solv_chksum_get_type(chk))
772       return 0;
773     b = solv_chksum_get($self, &l);
774     bo = solv_chksum_get(chk, 0);
775     return memcmp(b, bo, l) == 0;
776   }
777   bool __ne__(Chksum *chk) {
778     return !Chksum___eq__($self, chk);
779   }
780 #if defined(SWIGRUBY)
781   %rename("to_s") __str__;
782   %rename("inspect") __repr__;
783 #endif
784 #if defined(SWIGPERL)
785   %rename("str") __str__;
786 #endif
787   %newobject __str__;
788   const char *__str__() {
789     const char *str;
790     const char *h = 0;
791     if (solv_chksum_isfinished($self))
792       h = Chksum_hex($self);
793     str = solv_dupjoin(solv_chksum_type2str(solv_chksum_get_type($self)), ":", h ? h : "unfinished");
794     solv_free((void *)h);
795     return str;
796   }
797   %newobject __repr__;
798   const char *__repr__() {
799     const char *h = Chksum___str__($self);
800     const char *str = solv_dupjoin("<Chksum ", h, ">");
801     solv_free((void *)h);
802     return str;
803   }
804 }
805
806 %extend Pool {
807   Pool() {
808     Pool *pool = pool_create();
809     return pool;
810   }
811   ~Pool() {
812   }
813   void set_debuglevel(int level) {
814     pool_setdebuglevel($self, level);
815   }
816 #if defined(SWIGPYTHON)
817   %{
818   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
819     XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
820     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
821     PyObject *result = PyEval_CallObject((PyObject *)d, args);
822     int ecode = 0;
823     int vresult = 0;
824     Py_DECREF(args);
825     if (!result)
826       return 0; /* exception */
827     ecode = SWIG_AsVal_int(result, &vresult);
828     Py_DECREF(result);
829     return SWIG_IsOK(ecode) ? vresult : 0;
830   }
831   %}
832   void set_loadcallback(PyObject *callable) {
833     if ($self->loadcallback == loadcallback) {
834       Py_DECREF($self->loadcallbackdata);
835     }
836     if (callable) {
837       Py_INCREF(callable);
838     }
839     pool_setloadcallback($self, callable ? loadcallback : 0, callable);
840   }
841 #endif
842 #if defined(SWIGPERL)
843 %{
844   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
845     int count;
846     int ret = 0;
847     dSP;
848     XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
849
850     ENTER;
851     SAVETMPS;
852     PUSHMARK(SP);
853     XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_OWNER | SWIG_SHADOW));
854     PUTBACK;
855     count = perl_call_sv((SV *)d, G_EVAL|G_SCALAR);
856     SPAGAIN;
857     if (count)
858       ret = POPi;
859     PUTBACK;
860     FREETMPS;
861     LEAVE;
862     return ret;
863   }
864 %}
865   void set_loadcallback(SV *callable) {
866     if ($self->loadcallback == loadcallback)
867       SvREFCNT_dec($self->loadcallbackdata);
868     if (callable)
869       SvREFCNT_inc(callable);
870     pool_setloadcallback($self, callable ? loadcallback : 0, callable);
871   }
872 #endif
873
874 #if defined(SWIGRUBY)
875 %{
876   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
877     XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
878     VALUE callable = (VALUE)d;
879     VALUE rd = SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0);
880     VALUE res = rb_funcall(callable, rb_intern("call"), 1, rd);
881     return res == Qtrue;
882   }
883   SWIGINTERN void mark_Pool(void *ptr) {
884     Pool *pool = ptr;
885     if (pool->loadcallback == loadcallback && pool->loadcallbackdata) {
886       VALUE callable = (VALUE)pool->loadcallbackdata;
887       rb_gc_mark(callable);
888     }
889   }
890 %}
891   %typemap(in, numinputs=0) VALUE callable {
892     $1 = rb_block_given_p() ? rb_block_proc() : 0;
893   }
894   void set_loadcallback(VALUE callable) {
895     pool_setloadcallback($self, callable ? loadcallback : 0, (void *)callable);
896   }
897 #endif
898
899   void free() {
900     Pool_set_loadcallback($self, 0);
901     pool_free($self);
902   }
903   Id str2id(const char *str, bool create=1) {
904     return pool_str2id($self, str, create);
905   }
906   const char *id2str(Id id) {
907     return pool_id2str($self, id);
908   }
909   const char *dep2str(Id id) {
910     return pool_dep2str($self, id);
911   }
912   Id rel2id(Id name, Id evr, int flags, bool create=1) {
913     return pool_rel2id($self, name, evr, flags, create);
914   }
915   Id id2langid(Id id, const char *lang, bool create=1) {
916     return pool_id2langid($self, id, lang, create);
917   }
918   void setarch(const char *arch) {
919     pool_setarch($self, arch);
920   }
921   Repo *add_repo(const char *name) {
922     return repo_create($self, name);
923   }
924   const char *lookup_str(Id entry, Id keyname) {
925     return pool_lookup_str($self, entry, keyname);
926   }
927   Id lookup_id(Id entry, Id keyname) {
928     return pool_lookup_id($self, entry, keyname);
929   }
930   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
931     return pool_lookup_num($self, entry, keyname, notfound);
932   }
933   bool lookup_void(Id entry, Id keyname) {
934     return pool_lookup_void($self, entry, keyname);
935   }
936   %newobject lookup_checksum;
937   Chksum *lookup_checksum(Id entry, Id keyname) {
938     Id type = 0;
939     const unsigned char *b = pool_lookup_bin_checksum($self, entry, keyname, &type);
940     return solv_chksum_create_from_bin(type, b);
941   }
942
943   %newobject Dataiterator;
944   Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
945     return new_Dataiterator($self, 0, p, key, match, flags);
946   }
947   const char *solvid2str(Id solvid) {
948     return pool_solvid2str($self, solvid);
949   }
950   void addfileprovides() {
951     pool_addfileprovides($self);
952   }
953   Queue addfileprovides_ids() {
954     Queue r;
955     Id *addedfileprovides = 0;
956     queue_init(&r);
957     pool_addfileprovides_ids($self, $self->installed, &addedfileprovides);
958     if (addedfileprovides) {
959       for (; *addedfileprovides; addedfileprovides++)
960         queue_push(&r, *addedfileprovides);
961     }
962     return r;
963   }
964   void createwhatprovides() {
965     pool_createwhatprovides($self);
966   }
967
968   XSolvable *id2solvable(Id id) {
969     return new_XSolvable($self, id);
970   }
971   %newobject solvables;
972   Pool_solvable_iterator * const solvables;
973   %{
974   SWIGINTERN Pool_solvable_iterator * Pool_solvables_get(Pool *pool) {
975     return new_Pool_solvable_iterator(pool);
976   }
977   %}
978   %newobject solvables_iter;
979   Pool_solvable_iterator * solvables_iter() {
980     return new_Pool_solvable_iterator($self);
981   }
982
983   Repo *id2repo(Id id) {
984     if (id < 1 || id > $self->nrepos)
985       return 0;
986     return pool_id2repo($self, id);
987   }
988   %newobject repos;
989   Pool_repo_iterator * const repos;
990   %{
991   SWIGINTERN Pool_repo_iterator * Pool_repos_get(Pool *pool) {
992     return new_Pool_repo_iterator(pool);
993   }
994   %}
995   %newobject repos_iter;
996   Pool_repo_iterator * repos_iter() {
997     return new_Pool_repo_iterator($self);
998   }
999
1000   Repo *installed;
1001   %{
1002   SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
1003     pool_set_installed(pool, installed);
1004   }
1005   Repo *Pool_installed_get(Pool *pool) {
1006     return pool->installed;
1007   }
1008   %}
1009
1010   Queue matchprovidingids(const char *match, int flags) {
1011     Pool *pool = $self;
1012     Queue q;
1013     Id id;
1014     queue_init(&q);
1015     if (!flags) {
1016       for (id = 1; id < pool->ss.nstrings; id++)
1017         if (pool->whatprovides[id])
1018           queue_push(&q, id);
1019     } else {
1020       Datamatcher ma;
1021       if (!datamatcher_init(&ma, match, flags)) {
1022         for (id = 1; id < pool->ss.nstrings; id++)
1023           if (pool->whatprovides[id] && datamatcher_match(&ma, pool_id2str(pool, id)))
1024             queue_push(&q, id);
1025         datamatcher_free(&ma);
1026       }
1027     }
1028     return q;
1029   }
1030
1031   Job *Job(int how, Id what) {
1032     return new_Job($self, how, what);
1033   }
1034
1035   %typemap(out) Queue whatprovides Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
1036   %newobject whatprovides;
1037   Queue whatprovides(Id dep) {
1038     Pool *pool = $self;
1039     Queue q;
1040     Id p, pp;
1041     queue_init(&q);
1042     FOR_PROVIDES(p, pp, dep)
1043       queue_push(&q, p);
1044     return q;
1045   }
1046
1047   Id towhatprovides(Queue q) {
1048     return pool_queuetowhatprovides($self, &q);
1049   }
1050
1051 #ifdef SWIGRUBY
1052   %rename("isknownarch?") isknownarch;
1053 #endif
1054   bool isknownarch(Id id) {
1055     Pool *pool = $self;
1056     if (!id || id == ID_EMPTY)
1057       return 0;
1058     if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
1059       return 1;
1060     if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
1061       return 0;
1062     return 1;
1063   }
1064
1065   %newobject Solver;
1066   Solver *Solver() {
1067     return solver_create($self);
1068   }
1069 }
1070
1071 %extend Repo {
1072   static const int REPO_REUSE_REPODATA = REPO_REUSE_REPODATA;
1073   static const int REPO_NO_INTERNALIZE = REPO_NO_INTERNALIZE;
1074   static const int REPO_LOCALPOOL = REPO_LOCALPOOL;
1075   static const int REPO_USE_LOADING = REPO_USE_LOADING;
1076   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
1077   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
1078   static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES; /* repo_susetags */
1079   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS ; /* repo_solv */
1080
1081   void free(bool reuseids = 0) {
1082     repo_free($self, reuseids);
1083   }
1084   void empty(bool reuseids = 0) {
1085     repo_empty($self, reuseids);
1086   }
1087 #ifdef SWIGRUBY
1088   %rename("isempty?") isempty;
1089 #endif
1090   bool isempty() {
1091     return !$self->nsolvables;
1092   }
1093   bool add_solv(const char *name, int flags = 0) {
1094     FILE *fp = fopen(name, "r");
1095     int r;
1096     if (!fp)
1097       return 0;
1098     r = repo_add_solv_flags($self, fp, flags);
1099     fclose(fp);
1100     return r == 0;
1101   }
1102   bool add_solv(FILE *fp, int flags = 0) {
1103     return repo_add_solv_flags($self, fp, flags) == 0;
1104   }
1105   bool add_products(const char *proddir, int flags = 0) {
1106     repo_add_products($self, proddir, 0, flags);
1107     return 1;
1108   }
1109   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
1110     repo_add_rpmmd($self, fp, language, flags);
1111     return 1;
1112   }
1113 #ifndef DEBIAN
1114   bool add_rpmdb(Repo *ref, int flags = 0) {
1115     repo_add_rpmdb($self, ref, 0, flags);
1116     return 1;
1117   }
1118   Id add_rpm(const char *name, int flags = 0) {
1119     return repo_add_rpm($self, name, flags);
1120   }
1121 #endif
1122   bool add_debdb(int flags = 0) {
1123     repo_add_debdb($self, 0, flags);
1124     return 1;
1125   }
1126   Id add_deb(const char *name, int flags = 0) {
1127     return repo_add_deb($self, name, flags);
1128   }
1129   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
1130     repo_add_susetags($self, fp, defvendor, language, flags);
1131     return 1;
1132   }
1133   bool add_repomdxml(FILE *fp, int flags = 0) {
1134     repo_add_repomdxml($self, fp, flags);
1135     return 1;
1136   }
1137   bool add_content(FILE *fp, int flags = 0) {
1138     repo_add_content($self, fp, flags);
1139     return 1;
1140   }
1141   bool add_updateinfoxml(FILE *fp, int flags = 0) {
1142     repo_add_updateinfoxml($self, fp, flags);
1143     return 1;
1144   }
1145   bool add_deltainfoxml(FILE *fp, int flags = 0) {
1146     repo_add_deltainfoxml($self, fp, flags);
1147     return 1;
1148   }
1149   void internalize() {
1150     repo_internalize($self);
1151   }
1152   const char *lookup_str(Id entry, Id keyname) {
1153     return repo_lookup_str($self, entry, keyname);
1154   }
1155   Id lookup_id(Id entry, Id keyname) {
1156     return repo_lookup_id($self, entry, keyname);
1157   }
1158   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
1159     return repo_lookup_num($self, entry, keyname, notfound);
1160   }
1161   void write(FILE *fp) {
1162     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
1163   }
1164   # HACK, remove if no longer needed!
1165   bool write_first_repodata(FILE *fp) {
1166     int oldnrepodata = $self->nrepodata;
1167     $self->nrepodata = 1;
1168     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
1169     $self->nrepodata = oldnrepodata;
1170     return 1;
1171   }
1172
1173   %newobject Dataiterator;
1174   Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
1175     return new_Dataiterator($self->pool, $self, p, key, match, flags);
1176   }
1177
1178   Id const id;
1179   %{
1180   SWIGINTERN Id Repo_id_get(Repo *repo) {
1181     return repo->repoid;
1182   }
1183   %}
1184   Repo_solvable_iterator * const solvables;
1185   %{
1186   SWIGINTERN Repo_solvable_iterator * Repo_solvables_get(Repo *repo) {
1187     return new_Repo_solvable_iterator(repo);
1188   }
1189   %}
1190   %newobject solvables_iter;
1191   Repo_solvable_iterator *solvables_iter() {
1192     return new_Repo_solvable_iterator($self);
1193   }
1194
1195   XRepodata *add_repodata(int flags = 0) {
1196     Repodata *rd = repo_add_repodata($self, flags);
1197     return new_XRepodata($self, rd - $self->repodata);
1198   }
1199
1200   void create_stubs() {
1201     Repodata *data;
1202     if (!$self->nrepodata)
1203       return;
1204     data = $self->repodata  + ($self->nrepodata - 1);
1205     if (data->state != REPODATA_STUB)
1206       repodata_create_stubs(data);
1207   }
1208 #ifdef SWIGRUBY
1209   %rename("iscontiguous?") iscontiguous;
1210 #endif
1211   bool iscontiguous() {
1212     int i;
1213     for (i = $self->start; i < $self->end; i++)
1214       if ($self->pool->solvables[i].repo != $self)
1215         return 0;
1216     return 1;
1217   }
1218   XRepodata *first_repodata() {
1219      int i;
1220      if (!$self->nrepodata)
1221        return 0;
1222      /* make sure all repodatas but the first are extensions */
1223      if ($self->repodata[0].loadcallback)
1224         return 0;
1225      for (i = 1; i < $self->nrepodata; i++)
1226        if (!$self->repodata[i].loadcallback)
1227          return 0;       /* oops, not an extension */
1228      return new_XRepodata($self, 0);
1229    }
1230
1231   bool __eq__(Repo *repo) {
1232     return $self == repo;
1233   }
1234   bool __ne__(Repo *repo) {
1235     return $self != repo;
1236   }
1237 #if defined(SWIGPERL)
1238   %rename("str") __str__;
1239 #endif
1240   %newobject __str__;
1241   const char *__str__() {
1242     char buf[20];
1243     if ($self->name)
1244       return strdup($self->name);
1245     sprintf(buf, "Repo#%d", $self->repoid);
1246     return strdup(buf);
1247   }
1248   %newobject __repr__;
1249   const char *__repr__() {
1250     char buf[20];
1251     if ($self->name)
1252       {
1253         sprintf(buf, "<Repo #%d ", $self->repoid);
1254         return solv_dupjoin(buf, $self->name, ">");
1255       }
1256     sprintf(buf, "<Repo #%d>", $self->repoid);
1257     return strdup(buf);
1258   }
1259 }
1260
1261 %extend Dataiterator {
1262   static const int SEARCH_STRING = SEARCH_STRING;
1263   static const int SEARCH_SUBSTRING = SEARCH_SUBSTRING;
1264   static const int SEARCH_GLOB = SEARCH_GLOB;
1265   static const int SEARCH_REGEX = SEARCH_REGEX;
1266   static const int SEARCH_NOCASE = SEARCH_NOCASE;
1267   static const int SEARCH_FILES = SEARCH_FILES;
1268   static const int SEARCH_COMPLETE_FILELIST = SEARCH_COMPLETE_FILELIST;
1269
1270   Dataiterator(Pool *pool, Repo *repo, Id p, Id key, const char *match, int flags) {
1271     Dataiterator *di = solv_calloc(1, sizeof(*di));
1272     dataiterator_init(di, pool, repo, p, key, match, flags);
1273     return di;
1274   }
1275   ~Dataiterator() {
1276     dataiterator_free($self);
1277     solv_free($self);
1278   }
1279 #if defined(SWIGPYTHON)
1280   %newobject __iter__;
1281   Dataiterator *__iter__() {
1282     Dataiterator *ndi;
1283     ndi = solv_calloc(1, sizeof(*ndi));
1284     dataiterator_init_clone(ndi, $self);
1285     return ndi;
1286   }
1287   %rename("next") __next__();
1288   %exception __next__ {
1289     $action
1290     if (!result) {
1291       PyErr_SetString(PyExc_StopIteration,"no more matches");
1292       return NULL;
1293     }
1294   }
1295 #endif
1296
1297 #ifdef SWIGPERL
1298   perliter(solv::Dataiterator)
1299 #endif
1300
1301   %newobject __next__;
1302   Datamatch *__next__() {
1303     Dataiterator *ndi;
1304     if (!dataiterator_step($self)) {
1305       return 0;
1306     }
1307     ndi = solv_calloc(1, sizeof(*ndi));
1308     dataiterator_init_clone(ndi, $self);
1309     return ndi;
1310   }
1311 #ifdef SWIGRUBY
1312   void each() {
1313     Datamatch *d;
1314     while ((d = Dataiterator___next__($self)) != 0) {
1315       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(d), SWIGTYPE_p_Datamatch, SWIG_POINTER_OWN | 0));
1316     }
1317   }
1318 #endif
1319   void prepend_keyname(Id key) {
1320     dataiterator_prepend_keyname($self, key);
1321   }
1322   void skip_solvable() {
1323     dataiterator_skip_solvable($self);
1324   }
1325 }
1326
1327 %extend Datamatch {
1328   ~Datamatch() {
1329     dataiterator_free($self);
1330     solv_free($self);
1331   }
1332   %newobject solvable;
1333   XSolvable * const solvable;
1334   %{
1335   SWIGINTERN XSolvable *Datamatch_solvable_get(Dataiterator *di) {
1336     return new_XSolvable(di->pool, di->solvid);
1337   }
1338   %}
1339   Id key_id() {
1340     return $self->key->name;
1341   }
1342   const char *key_idstr() {
1343     return pool_id2str($self->pool, $self->key->name);
1344   }
1345   Id type_id() {
1346     return $self->key->type;
1347   }
1348   const char *type_idstr() {
1349     return pool_id2str($self->pool, $self->key->type);
1350   }
1351   Id id() {
1352      return $self->kv.id;
1353   }
1354   const char *idstr() {
1355      return pool_id2str($self->pool, $self->kv.id);
1356   }
1357   const char *str() {
1358      return $self->kv.str;
1359   }
1360   int num() {
1361      return $self->kv.num;
1362   }
1363   int num2() {
1364      return $self->kv.num2;
1365   }
1366   void setpos() {
1367     dataiterator_setpos($self);
1368   }
1369   void setpos_parent() {
1370     dataiterator_setpos_parent($self);
1371   }
1372 }
1373
1374 %extend Pool_solvable_iterator {
1375   Pool_solvable_iterator(Pool *pool) {
1376     Pool_solvable_iterator *s;
1377     s = solv_calloc(1, sizeof(*s));
1378     s->pool = pool;
1379     return s;
1380   }
1381 #if defined(SWIGPYTHON)
1382   %newobject __iter__;
1383   Pool_solvable_iterator *__iter__() {
1384     Pool_solvable_iterator *s;
1385     s = solv_calloc(1, sizeof(*s));
1386     *s = *$self;
1387     return s;
1388   }
1389   %rename("next") __next__();
1390   %exception __next__ {
1391     $action
1392     if (!result) {
1393       PyErr_SetString(PyExc_StopIteration,"no more matches");
1394       return NULL;
1395     }
1396   }
1397 #endif
1398
1399 #ifdef SWIGPERL
1400   perliter(solv::Pool_solvable_iterator)
1401 #endif
1402   %newobject __next__;
1403   XSolvable *__next__() {
1404     Pool *pool = $self->pool;
1405     if ($self->id >= pool->nsolvables)
1406       return 0;
1407     while (++$self->id < pool->nsolvables)
1408       if (pool->solvables[$self->id].repo)
1409         return new_XSolvable(pool, $self->id);
1410     return 0;
1411   }
1412 #ifdef SWIGRUBY
1413   void each() {
1414     XSolvable *n;
1415     while ((n = Pool_solvable_iterator___next__($self)) != 0) {
1416       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
1417     }
1418   }
1419 #endif
1420   %newobject __getitem__;
1421   XSolvable *__getitem__(Id key) {
1422     Pool *pool = $self->pool;
1423     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo)
1424       return new_XSolvable(pool, key);
1425     return 0;
1426   }
1427   int __len__() {
1428     return $self->pool->nsolvables;
1429   }
1430 }
1431
1432 %extend Pool_repo_iterator {
1433   Pool_repo_iterator(Pool *pool) {
1434     Pool_repo_iterator *s;
1435     s = solv_calloc(1, sizeof(*s));
1436     s->pool = pool;
1437     return s;
1438   }
1439 #if defined(SWIGPYTHON)
1440   %newobject __iter__;
1441   Pool_repo_iterator *__iter__() {
1442     Pool_repo_iterator *s;
1443     s = solv_calloc(1, sizeof(*s));
1444     *s = *$self;
1445     return s;
1446   }
1447   %rename("next") __next__();
1448   %exception __next__ {
1449     $action
1450     if (!result) {
1451       PyErr_SetString(PyExc_StopIteration,"no more matches");
1452       return NULL;
1453     }
1454   }
1455 #endif
1456   %newobject __next__;
1457   Repo *__next__() {
1458     Pool *pool = $self->pool;
1459     if ($self->id >= pool->nrepos + 1)
1460       return 0;
1461     while (++$self->id < pool->nrepos + 1) {
1462       Repo *r = pool_id2repo(pool, $self->id);
1463       if (r)
1464         return r;
1465     }
1466     return 0;
1467   }
1468 #ifdef SWIGRUBY
1469   void each() {
1470     Repo *n;
1471     while ((n = Pool_repo_iterator___next__($self)) != 0) {
1472       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p__Repo, SWIG_POINTER_OWN | 0));
1473     }
1474   }
1475 #endif
1476   Repo *__getitem__(Id key) {
1477     Pool *pool = $self->pool;
1478     if (key > 0 && key < pool->nrepos + 1)
1479       return pool_id2repo(pool, key);
1480     return 0;
1481   }
1482   int __len__() {
1483     return $self->pool->nrepos + 1;
1484   }
1485 }
1486
1487 %extend Repo_solvable_iterator {
1488   Repo_solvable_iterator(Repo *repo) {
1489     Repo_solvable_iterator *s;
1490     s = solv_calloc(1, sizeof(*s));
1491     s->repo = repo;
1492     return s;
1493   }
1494 #if defined(SWIGPYTHON)
1495   %newobject __iter__;
1496   Repo_solvable_iterator *__iter__() {
1497     Repo_solvable_iterator *s;
1498     s = solv_calloc(1, sizeof(*s));
1499     *s = *$self;
1500     return s;
1501   }
1502   %rename("next") __next__();
1503   %exception __next__ {
1504     $action
1505     if (!result) {
1506       PyErr_SetString(PyExc_StopIteration,"no more matches");
1507       return NULL;
1508     }
1509   }
1510 #endif
1511   %newobject __next__;
1512   XSolvable *__next__() {
1513     Repo *repo = $self->repo;
1514     Pool *pool = repo->pool;
1515     if (repo->start > 0 && $self->id < repo->start)
1516       $self->id = repo->start - 1;
1517     if ($self->id >= repo->end)
1518       return 0;
1519     while (++$self->id < repo->end)
1520       if (pool->solvables[$self->id].repo == repo)
1521         return new_XSolvable(pool, $self->id);
1522     return 0;
1523   }
1524 #ifdef SWIGRUBY
1525   void each() {
1526     XSolvable *n;
1527     while ((n = Repo_solvable_iterator___next__($self)) != 0) {
1528       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
1529     }
1530   }
1531 #endif
1532   %newobject __getitem__;
1533   XSolvable *__getitem__(Id key) {
1534     Repo *repo = $self->repo;
1535     Pool *pool = repo->pool;
1536     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo == repo)
1537       return new_XSolvable(pool, key);
1538     return 0;
1539   }
1540   int __len__() {
1541     return $self->repo->pool->nsolvables;
1542   }
1543 }
1544
1545 %extend Dep {
1546   Dep(Pool *pool, Id id) {
1547     Dep *s;
1548     if (!id)
1549       return 0;
1550     s = solv_calloc(1, sizeof(*s));
1551     s->pool = pool;
1552     s->id = id;
1553     return s;
1554   }
1555   const char *str() {
1556     return pool_dep2str($self->pool, $self->id);
1557   }
1558   bool __eq__(Dep *s) {
1559     return $self->pool == s->pool && $self->id == s->id;
1560   }
1561   bool __ne__(Dep *s) {
1562     return !Dep___eq__($self, s);
1563   }
1564 #if defined(SWIGPERL)
1565   %rename("str") __str__;
1566 #endif
1567   const char *__str__() {
1568     return pool_dep2str($self->pool, $self->id);
1569   }
1570   %newobject __repr__;
1571   const char *__repr__() {
1572     char buf[20];
1573     sprintf(buf, "<Id #%d ", $self->id);
1574     return solv_dupjoin(buf, pool_dep2str($self->pool, $self->id), ">");
1575   }
1576 }
1577
1578 %extend XSolvable {
1579   XSolvable(Pool *pool, Id id) {
1580     XSolvable *s;
1581     if (!id || id >= pool->nsolvables)
1582       return 0;
1583     s = solv_calloc(1, sizeof(*s));
1584     s->pool = pool;
1585     s->id = id;
1586     return s;
1587   }
1588   const char *str() {
1589     return pool_solvid2str($self->pool, $self->id);
1590   }
1591   const char *lookup_str(Id keyname) {
1592     return pool_lookup_str($self->pool, $self->id, keyname);
1593   }
1594   Id lookup_id(Id keyname) {
1595     return pool_lookup_id($self->pool, $self->id, keyname);
1596   }
1597   unsigned int lookup_num(Id keyname, unsigned int notfound = 0) {
1598     return pool_lookup_num($self->pool, $self->id, keyname, notfound);
1599   }
1600   bool lookup_void(Id keyname) {
1601     return pool_lookup_void($self->pool, $self->id, keyname);
1602   }
1603   %newobject lookup_checksum;
1604   Chksum *lookup_checksum(Id keyname) {
1605     Id type = 0;
1606     const unsigned char *b = pool_lookup_bin_checksum($self->pool, $self->id, keyname, &type);
1607     return solv_chksum_create_from_bin(type, b);
1608   }
1609   const char *lookup_location(unsigned int *OUTPUT) {
1610     return solvable_get_location($self->pool->solvables + $self->id, OUTPUT);
1611   }
1612 #ifdef SWIGRUBY
1613   %rename("installable?") installable;
1614 #endif
1615   bool installable() {
1616     return pool_installable($self->pool, pool_id2solvable($self->pool, $self->id));
1617   }
1618 #ifdef SWIGRUBY
1619   %rename("isinstalled?") isinstalled;
1620 #endif
1621   bool isinstalled() {
1622     Pool *pool = $self->pool;
1623     return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed;
1624   }
1625
1626   const char * const name;
1627   %{
1628     SWIGINTERN const char *XSolvable_name_get(XSolvable *xs) {
1629       Pool *pool = xs->pool;
1630       return pool_id2str(pool, pool->solvables[xs->id].name);
1631     }
1632   %}
1633   Id const nameid;
1634   %{
1635     SWIGINTERN Id XSolvable_nameid_get(XSolvable *xs) {
1636       return xs->pool->solvables[xs->id].name;
1637     }
1638   %}
1639   const char * const evr;
1640   %{
1641     SWIGINTERN const char *XSolvable_evr_get(XSolvable *xs) {
1642       Pool *pool = xs->pool;
1643       return pool_id2str(pool, pool->solvables[xs->id].evr);
1644     }
1645   %}
1646   Id const evrid;
1647   %{
1648     SWIGINTERN Id XSolvable_evrid_get(XSolvable *xs) {
1649       return xs->pool->solvables[xs->id].evr;
1650     }
1651   %}
1652   const char * const arch;
1653   %{
1654     SWIGINTERN const char *XSolvable_arch_get(XSolvable *xs) {
1655       Pool *pool = xs->pool;
1656       return pool_id2str(pool, pool->solvables[xs->id].arch);
1657     }
1658   %}
1659   Id const archid;
1660   %{
1661     SWIGINTERN Id XSolvable_archid_get(XSolvable *xs) {
1662       return xs->pool->solvables[xs->id].arch;
1663     }
1664   %}
1665   const char * const vendor;
1666   %{
1667     SWIGINTERN const char *XSolvable_vendor_get(XSolvable *xs) {
1668       Pool *pool = xs->pool;
1669       return pool_id2str(pool, pool->solvables[xs->id].vendor);
1670     }
1671   %}
1672   Id const vendorid;
1673   %{
1674     SWIGINTERN Id XSolvable_vendorid_get(XSolvable *xs) {
1675       return xs->pool->solvables[xs->id].vendor;
1676     }
1677   %}
1678   Repo * const repo;
1679   %{
1680     SWIGINTERN Repo *XSolvable_repo_get(XSolvable *xs) {
1681       return xs->pool->solvables[xs->id].repo;
1682     }
1683   %}
1684
1685   bool __eq__(XSolvable *s) {
1686     return $self->pool == s->pool && $self->id == s->id;
1687   }
1688   bool __ne__(XSolvable *s) {
1689     return !XSolvable___eq__($self, s);
1690   }
1691 #if defined(SWIGPERL)
1692   %rename("str") __str__;
1693 #endif
1694   const char *__str__() {
1695     return pool_solvid2str($self->pool, $self->id);
1696   }
1697   %newobject __repr__;
1698   const char *__repr__() {
1699     char buf[20];
1700     sprintf(buf, "<Solvable #%d ", $self->id);
1701     return solv_dupjoin(buf, pool_solvid2str($self->pool, $self->id), ">");
1702   }
1703 }
1704
1705 %extend Problem {
1706   Problem(Solver *solv, Id id) {
1707     Problem *p;
1708     p = solv_calloc(1, sizeof(*p));
1709     p->solv = solv;
1710     p->id = id;
1711     return p;
1712   }
1713   %newobject findproblemrule;
1714   XRule *findproblemrule() {
1715     Id r = solver_findproblemrule($self->solv, $self->id);
1716     return new_XRule($self->solv, r);
1717   }
1718   %newobject findallproblemrules;
1719   %typemap(out) Queue findallproblemrules Queue2Array(XRule *, 1, new_XRule(arg1->solv, id));
1720   Queue findallproblemrules(int unfiltered=0) {
1721     Solver *solv = $self->solv;
1722     Id probr;
1723     int i, j;
1724     Queue q;
1725     queue_init(&q);
1726     solver_findallproblemrules(solv, $self->id, &q);
1727     if (!unfiltered)
1728       {
1729         for (i = j = 0; i < q.count; i++)
1730           {
1731             probr = q.elements[i];
1732             if ((probr >= solv->updaterules && probr < solv->updaterules_end) || (probr >= solv->jobrules && probr < solv->jobrules_end))
1733               continue;
1734             q.elements[j++] = probr;
1735           }
1736         if (j)
1737           queue_truncate(&q, j);
1738       }
1739     return q;
1740   }
1741   int solution_count() {
1742     return solver_solution_count($self->solv, $self->id);
1743   }
1744   %newobject solutions;
1745   %typemap(out) Queue solutions Queue2Array(Solution *, 1, new_Solution(arg1, id));
1746   Queue solutions() {
1747     Queue q;
1748     int i, cnt;
1749     queue_init(&q);
1750     cnt = solver_solution_count($self->solv, $self->id);
1751     for (i = 1; i <= cnt; i++)
1752       queue_push(&q, i);
1753     return q;
1754   }
1755 }
1756
1757 %extend Solution {
1758   Solution(Problem *p, Id id) {
1759     Solution *s;
1760     s = solv_calloc(1, sizeof(*s));
1761     s->solv = p->solv;
1762     s->problemid = p->id;
1763     s->id = id;
1764     return s;
1765   }
1766   int element_count() {
1767     return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
1768   }
1769
1770   %newobject elements;
1771   %typemap(out) Queue elements Queue2Array(Solutionelement *, 4, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2], idp[3]));
1772   Queue elements(bool expandreplaces=0) {
1773     Queue q;
1774     int i, cnt;
1775     queue_init(&q);
1776     cnt = solver_solutionelement_count($self->solv, $self->problemid, $self->id);
1777     for (i = 1; i <= cnt; i++)
1778       {
1779         Id p, rp, type;
1780         solver_next_solutionelement($self->solv, $self->problemid, $self->id, i - 1, &p, &rp);
1781         if (p > 0) {
1782           type = rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE;
1783         } else {
1784           type = p;
1785           p = rp;
1786           rp = 0;
1787         }
1788         if (type == SOLVER_SOLUTION_REPLACE && expandreplaces) {
1789           int illegal = policy_is_illegal(self->solv, self->solv->pool->solvables + p, self->solv->pool->solvables + rp, 0);
1790           if (illegal) {
1791             if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) {
1792               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
1793               queue_push2(&q, p, rp);
1794             }
1795             if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) {
1796               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
1797               queue_push2(&q, p, rp);
1798             }
1799             if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) {
1800               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
1801               queue_push2(&q, p, rp);
1802             }
1803             continue;
1804           }
1805         }
1806         queue_push2(&q, i, type);
1807         queue_push2(&q, p, rp);
1808       }
1809     return q;
1810   }
1811 }
1812
1813 %extend Solutionelement {
1814   Solutionelement(Solver *solv, Id problemid, Id solutionid, Id id, Id type, Id p, Id rp) {
1815     Solutionelement *e;
1816     e = solv_calloc(1, sizeof(*e));
1817     e->solv = solv;
1818     e->problemid = problemid;
1819     e->solutionid = id;
1820     e->id = id;
1821     e->type = type;
1822     e->p = p;
1823     e->rp = rp;
1824     return e;
1825   }
1826   const char *str() {
1827     Id p = $self->type;
1828     Id rp = $self->p;
1829     if (p == SOLVER_SOLUTION_ERASE)
1830       {
1831         p = rp;
1832         rp = 0;
1833       }
1834     else if (p == SOLVER_SOLUTION_REPLACE)
1835       {
1836         p = rp;
1837         rp = $self->rp;
1838       }
1839     else if (p == SOLVER_SOLUTION_REPLACE_DOWNGRADE)
1840       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);
1841     else if (p == SOLVER_SOLUTION_REPLACE_ARCHCHANGE)
1842       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);
1843     else if (p == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
1844       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);
1845     return solver_solutionelement2str($self->solv, p, rp);
1846   }
1847   %newobject replaceelements;
1848   %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, arg1->id, id, arg1->p, arg1->rp));
1849   Queue replaceelements() {
1850     Queue q;
1851     int illegal;
1852
1853     queue_init(&q);
1854     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
1855       illegal = 0;
1856     else
1857       illegal = policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
1858     if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
1859       queue_push(&q, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
1860     if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
1861       queue_push(&q, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
1862     if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
1863       queue_push(&q, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
1864     if (!q.count)
1865       queue_push(&q, $self->type);
1866     return q;
1867   }
1868   int illegalreplace() {
1869     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
1870       return 0;
1871     return policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
1872   }
1873   %newobject solvable;
1874   XSolvable * const solvable;
1875   %newobject replacement;
1876   XSolvable * const replacement;
1877   int const jobidx;
1878   %{
1879     SWIGINTERN XSolvable *Solutionelement_solvable_get(Solutionelement *e) {
1880       return new_XSolvable(e->solv->pool, e->p);
1881     }
1882     SWIGINTERN XSolvable *Solutionelement_replacement_get(Solutionelement *e) {
1883       return new_XSolvable(e->solv->pool, e->rp);
1884     }
1885     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
1886       return (e->p - 1) / 2;
1887     }
1888   %}
1889   %newobject Job;
1890   Job *Job() {
1891     if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE)
1892       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->p);
1893     if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
1894       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->rp);
1895     if ($self->type == SOLVER_SOLUTION_ERASE)
1896       return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE, $self->p);
1897     return 0;
1898   }
1899 }
1900
1901 %extend Solver {
1902   static const int SOLVER_RULE_UNKNOWN = SOLVER_RULE_UNKNOWN;
1903   static const int SOLVER_RULE_RPM = SOLVER_RULE_RPM;
1904   static const int SOLVER_RULE_RPM_NOT_INSTALLABLE = SOLVER_RULE_RPM_NOT_INSTALLABLE;
1905   static const int SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP = SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP;
1906   static const int SOLVER_RULE_RPM_PACKAGE_REQUIRES = SOLVER_RULE_RPM_PACKAGE_REQUIRES;
1907   static const int SOLVER_RULE_RPM_SELF_CONFLICT = SOLVER_RULE_RPM_SELF_CONFLICT;
1908   static const int SOLVER_RULE_RPM_PACKAGE_CONFLICT = SOLVER_RULE_RPM_PACKAGE_CONFLICT;
1909   static const int SOLVER_RULE_RPM_SAME_NAME = SOLVER_RULE_RPM_SAME_NAME;
1910   static const int SOLVER_RULE_RPM_PACKAGE_OBSOLETES = SOLVER_RULE_RPM_PACKAGE_OBSOLETES;
1911   static const int SOLVER_RULE_RPM_IMPLICIT_OBSOLETES = SOLVER_RULE_RPM_IMPLICIT_OBSOLETES;
1912   static const int SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES = SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES;
1913   static const int SOLVER_RULE_UPDATE = SOLVER_RULE_UPDATE;
1914   static const int SOLVER_RULE_FEATURE = SOLVER_RULE_FEATURE;
1915   static const int SOLVER_RULE_JOB = SOLVER_RULE_JOB;
1916   static const int SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP = SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP;
1917   static const int SOLVER_RULE_DISTUPGRADE = SOLVER_RULE_DISTUPGRADE;
1918   static const int SOLVER_RULE_INFARCH = SOLVER_RULE_INFARCH;
1919   static const int SOLVER_RULE_CHOICE = SOLVER_RULE_CHOICE;
1920   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
1921
1922   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
1923   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
1924   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
1925   static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE;
1926   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
1927   static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE;
1928   static const int SOLVER_SOLUTION_REPLACE_ARCHCHANGE = SOLVER_SOLUTION_REPLACE_ARCHCHANGE;
1929   static const int SOLVER_SOLUTION_REPLACE_VENDORCHANGE = SOLVER_SOLUTION_REPLACE_VENDORCHANGE;
1930
1931   static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE;
1932   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
1933   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
1934
1935   ~Solver() {
1936     solver_free($self);
1937   }
1938 #if defined(SWIGPYTHON)
1939   %pythoncode {
1940     def solve(self, jobs):
1941       j = []
1942       for job in jobs: j += [job.how, job.what]
1943       return self.solve_helper(j)
1944   }
1945 #endif
1946 #if defined(SWIGPERL)
1947   %perlcode {
1948     sub solv::Solver::solve {
1949       my ($self, $jobs) = @_;
1950       my @j = map {($_->{'how'}, $_->{'what'})} @$jobs;
1951       return $self->solve_helper(\@j);
1952     }
1953   }
1954 #endif
1955 #if defined(SWIGRUBY)
1956 %init %{
1957 rb_eval_string(
1958     "class Solv::Solver\n"
1959     "  def solve(jobs)\n"
1960     "    jl = []\n"
1961     "    jobs.each do |j| ; jl << j.how << j.what ; end\n"
1962     "    solve_helper(jl)\n"
1963     "  end\n"
1964     "end\n"
1965   );
1966 %}
1967 #endif
1968   %typemap(out) Queue solve_helper Queue2Array(Problem *, 1, new_Problem(arg1, id));
1969   %newobject solve_helper;
1970   Queue solve_helper(Queue jobs) {
1971     Queue q;
1972     int i, cnt;
1973     queue_init(&q);
1974     solver_solve($self, &jobs);
1975     cnt = solver_problem_count($self);
1976     for (i = 1; i <= cnt; i++)
1977       queue_push(&q, i);
1978     return q;
1979   }
1980   %newobject transaction;
1981   Transaction *transaction() {
1982     return solver_create_transaction($self);
1983   }
1984 }
1985
1986 %extend Transaction {
1987   static const int SOLVER_TRANSACTION_IGNORE = SOLVER_TRANSACTION_IGNORE;
1988   static const int SOLVER_TRANSACTION_ERASE = SOLVER_TRANSACTION_ERASE;
1989   static const int SOLVER_TRANSACTION_REINSTALLED = SOLVER_TRANSACTION_REINSTALLED;
1990   static const int SOLVER_TRANSACTION_DOWNGRADED = SOLVER_TRANSACTION_DOWNGRADED;
1991   static const int SOLVER_TRANSACTION_CHANGED = SOLVER_TRANSACTION_CHANGED;
1992   static const int SOLVER_TRANSACTION_UPGRADED = SOLVER_TRANSACTION_UPGRADED;
1993   static const int SOLVER_TRANSACTION_OBSOLETED = SOLVER_TRANSACTION_OBSOLETED;
1994   static const int SOLVER_TRANSACTION_INSTALL = SOLVER_TRANSACTION_INSTALL;
1995   static const int SOLVER_TRANSACTION_REINSTALL = SOLVER_TRANSACTION_REINSTALL;
1996   static const int SOLVER_TRANSACTION_DOWNGRADE = SOLVER_TRANSACTION_DOWNGRADE;
1997   static const int SOLVER_TRANSACTION_CHANGE = SOLVER_TRANSACTION_CHANGE;
1998   static const int SOLVER_TRANSACTION_UPGRADE = SOLVER_TRANSACTION_UPGRADE;
1999   static const int SOLVER_TRANSACTION_OBSOLETES = SOLVER_TRANSACTION_OBSOLETES;
2000   static const int SOLVER_TRANSACTION_MULTIINSTALL = SOLVER_TRANSACTION_MULTIINSTALL;
2001   static const int SOLVER_TRANSACTION_MULTIREINSTALL = SOLVER_TRANSACTION_MULTIREINSTALL;
2002   static const int SOLVER_TRANSACTION_MAXTYPE = SOLVER_TRANSACTION_MAXTYPE;
2003   static const int SOLVER_TRANSACTION_SHOW_ACTIVE = SOLVER_TRANSACTION_SHOW_ACTIVE;
2004   static const int SOLVER_TRANSACTION_SHOW_ALL = SOLVER_TRANSACTION_SHOW_ALL;
2005   static const int SOLVER_TRANSACTION_SHOW_OBSOLETES = SOLVER_TRANSACTION_SHOW_OBSOLETES;
2006   static const int SOLVER_TRANSACTION_SHOW_MULTIINSTALL = SOLVER_TRANSACTION_SHOW_MULTIINSTALL;
2007   static const int SOLVER_TRANSACTION_CHANGE_IS_REINSTALL = SOLVER_TRANSACTION_CHANGE_IS_REINSTALL;
2008   static const int SOLVER_TRANSACTION_MERGE_VENDORCHANGES = SOLVER_TRANSACTION_MERGE_VENDORCHANGES;
2009   static const int SOLVER_TRANSACTION_MERGE_ARCHCHANGES = SOLVER_TRANSACTION_MERGE_ARCHCHANGES;
2010   static const int SOLVER_TRANSACTION_RPM_ONLY = SOLVER_TRANSACTION_RPM_ONLY;
2011   static const int SOLVER_TRANSACTION_ARCHCHANGE = SOLVER_TRANSACTION_ARCHCHANGE;
2012   static const int SOLVER_TRANSACTION_VENDORCHANGE = SOLVER_TRANSACTION_VENDORCHANGE;
2013   static const int SOLVER_TRANSACTION_KEEP_ORDERDATA = SOLVER_TRANSACTION_KEEP_ORDERDATA;
2014   ~Transaction() {
2015     transaction_free($self);
2016   }
2017 #ifdef SWIGRUBY
2018   %rename("isempty?") isempty;
2019 #endif
2020   bool isempty() {
2021     return $self->steps.count == 0;
2022   }
2023
2024   %newobject othersolvable;
2025   XSolvable *othersolvable(XSolvable *s) {
2026     Id op = transaction_obs_pkg($self, s->id);
2027     return new_XSolvable($self->pool, op);
2028   }
2029
2030   %newobject allothersolvables;
2031   %typemap(out) Queue allothersolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2032   Queue allothersolvables(XSolvable *s) {
2033     Queue q;
2034     queue_init(&q);
2035     transaction_all_obs_pkgs($self, s->id, &q);
2036     return q;
2037   }
2038
2039   %typemap(out) Queue classify Queue2Array(TransactionClass *, 4, new_TransactionClass(arg1, arg2, id, idp[1], idp[2], idp[3]));
2040   %newobject classify;
2041   Queue classify(int mode = 0) {
2042     Queue q;
2043     queue_init(&q);
2044     transaction_classify($self, mode, &q);
2045     return q;
2046   }
2047
2048   %typemap(out) Queue newpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2049   %newobject newpackages;
2050   Queue newpackages() {
2051     Queue q;
2052     int cut;
2053     queue_init(&q);
2054     cut = transaction_installedresult(self, &q);
2055     queue_truncate(&q, cut);
2056     return q;
2057   }
2058
2059   %typemap(out) Queue keptpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2060   %newobject keptpackages;
2061   Queue keptpackages() {
2062     Queue q;
2063     int cut;
2064     queue_init(&q);
2065     cut = transaction_installedresult(self, &q);
2066     if (cut)
2067       queue_deleten(&q, 0, cut);
2068     return q;
2069   }
2070
2071   %typemap(out) Queue steps Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
2072   %newobject steps ;
2073   Queue steps() {
2074     Queue q;
2075     queue_init_clone(&q, &$self->steps);
2076     return q;
2077   }
2078
2079   int steptype(XSolvable *s, int mode) {
2080     return transaction_type($self, s->id, mode);
2081   }
2082   int calc_installsizechange() {
2083     return transaction_calc_installsizechange($self);
2084   }
2085   void order(int flags) {
2086     transaction_order($self, flags);
2087   }
2088 }
2089
2090 %extend TransactionClass {
2091   TransactionClass(Transaction *trans, int mode, Id type, int count, Id fromid, Id toid) {
2092     TransactionClass *cl = solv_calloc(1, sizeof(*cl));
2093     cl->transaction = trans;
2094     cl->mode = mode;
2095     cl->type = type;
2096     cl->count = count;
2097     cl->fromid = fromid;
2098     cl->toid = toid;
2099     return cl;
2100   }
2101   %newobject solvables;
2102   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->transaction->pool, id));
2103   Queue solvables() {
2104     Queue q;
2105     queue_init(&q);
2106     transaction_classify_pkgs($self->transaction, $self->mode, $self->type, $self->fromid, $self->toid, &q);
2107     return q;
2108   }
2109 }
2110
2111 %extend XRule {
2112   XRule(Solver *solv, Id id) {
2113     if (!id)
2114       return 0;
2115     XRule *xr = solv_calloc(1, sizeof(*xr));
2116     xr->solv = solv;
2117     xr->id = id;
2118     return xr;
2119   }
2120   Ruleinfo *info() {
2121     Id type, source, target, dep;
2122     type =  solver_ruleinfo($self->solv, $self->id, &source, &target, &dep);
2123     return new_Ruleinfo($self, type, source, target, dep);
2124   }
2125   %typemap(out) Queue allinfos Queue2Array(Ruleinfo *, 4, new_Ruleinfo(arg1, id, idp[1], idp[2], idp[3]));
2126   %newobject allinfos;
2127   Queue allinfos() {
2128     Queue q;
2129     queue_init(&q);
2130     solver_allruleinfos($self->solv, $self->id, &q);
2131     return q;
2132   }
2133
2134   bool __eq__(XRule *xr) {
2135     return $self->solv == xr->solv && $self->id == xr->id;
2136   }
2137   bool __ne__(XRule *xr) {
2138     return !XRule___eq__($self, xr);
2139   }
2140   %newobject __repr__;
2141   const char *__repr__() {
2142     char buf[20];
2143     sprintf(buf, "<Rule #%d>", $self->id);
2144     return strdup(buf);
2145   }
2146 }
2147
2148 %extend Ruleinfo {
2149   Ruleinfo(XRule *r, Id type, Id source, Id target, Id dep) {
2150     Ruleinfo *ri = solv_calloc(1, sizeof(*ri));
2151     ri->solv = r->solv;
2152     ri->rid = r->id;
2153     ri->type = type;
2154     ri->source = source;
2155     ri->target = target;
2156     ri->dep = dep;
2157     return ri;
2158   }
2159   XSolvable * const solvable;
2160   XSolvable * const othersolvable;
2161   %{
2162     SWIGINTERN XSolvable *Ruleinfo_solvable_get(Ruleinfo *ri) {
2163       return new_XSolvable(ri->solv->pool, ri->source);
2164     }
2165     SWIGINTERN XSolvable *Ruleinfo_othersolvable_get(Ruleinfo *ri) {
2166       return new_XSolvable(ri->solv->pool, ri->target);
2167     }
2168   %}
2169   const char *problemstr() {
2170     return solver_problemruleinfo2str($self->solv, $self->type, $self->source, $self->target, $self->dep);
2171   }
2172 }
2173
2174 %extend XRepodata {
2175   XRepodata(Repo *repo, Id id) {
2176     XRepodata *xr = solv_calloc(1, sizeof(*xr));
2177     xr->repo = repo;
2178     xr->id = id;
2179     return xr;
2180   }
2181   Id new_handle() {
2182     return repodata_new_handle($self->repo->repodata + $self->id);
2183   }
2184   void set_id(Id solvid, Id keyname, Id id) {
2185     repodata_set_id($self->repo->repodata + $self->id, solvid, keyname, id);
2186   }
2187   void set_str(Id solvid, Id keyname, const char *str) {
2188     repodata_set_str($self->repo->repodata + $self->id, solvid, keyname, str);
2189   }
2190   void set_poolstr(Id solvid, Id keyname, const char *str) {
2191     repodata_set_poolstr($self->repo->repodata + $self->id, solvid, keyname, str);
2192   }
2193   void add_idarray(Id solvid, Id keyname, Id id) {
2194     repodata_add_idarray($self->repo->repodata + $self->id, solvid, keyname, id);
2195   }
2196   void add_flexarray(Id solvid, Id keyname, Id handle) {
2197     repodata_add_flexarray($self->repo->repodata + $self->id, solvid, keyname, handle);
2198   }
2199   void set_checksum(Id solvid, Id keyname, Chksum *chksum) {
2200     const unsigned char *buf = solv_chksum_get(chksum, 0);
2201     if (buf)
2202       repodata_set_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, solv_chksum_get_type(chksum), buf);
2203   }
2204   const char *lookup_str(Id solvid, Id keyname) {
2205     return repodata_lookup_str($self->repo->repodata + $self->id, solvid, keyname);
2206   }
2207   Queue lookup_idarray(Id solvid, Id keyname) {
2208     Queue r;
2209     queue_init(&r);
2210     repodata_lookup_idarray($self->repo->repodata + $self->id, solvid, keyname, &r);
2211     return r;
2212   }
2213   %newobject lookup_checksum;
2214   Chksum *lookup_checksum(Id solvid, Id keyname) {
2215     Id type = 0;
2216     const unsigned char *b = repodata_lookup_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, &type);
2217     return solv_chksum_create_from_bin(type, b);
2218   }
2219   void internalize() {
2220     repodata_internalize($self->repo->repodata + $self->id);
2221   }
2222   void create_stubs() {
2223     repodata_create_stubs($self->repo->repodata + $self->id);
2224   }
2225   void write(FILE *fp) {
2226     repodata_write($self->repo->repodata + $self->id, fp, repo_write_stdkeyfilter, 0);
2227   }
2228   bool add_solv(FILE *fp, int flags = 0) {
2229     Repodata *data = $self->repo->repodata + $self->id;
2230     int r, oldstate = data->state;
2231     data->state = REPODATA_LOADING;
2232     r = repo_add_solv_flags(data->repo, fp, flags | REPO_USE_LOADING);
2233     if (r || data->state == REPODATA_LOADING)
2234       data->state = oldstate;
2235     return r;
2236   }
2237   void extend_to_repo() {
2238     Repodata *data = $self->repo->repodata + $self->id;
2239     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
2240   }
2241   bool __eq__(XRepodata *xr) {
2242     return $self->repo == xr->repo && $self->id == xr->id;
2243   }
2244   bool __ne__(XRepodata *xr) {
2245     return !XRepodata___eq__($self, xr);
2246   }
2247   %newobject __repr__;
2248   const char *__repr__() {
2249     char buf[20];
2250     sprintf(buf, "<Repodata #%d>", $self->id);
2251     return strdup(buf);
2252   }
2253 }
2254