- rename pysolv.pt to pysolv, commit latest versions
[platform/upstream/libsolv.git] / examples / solv.i
1 #
2 ##if defined(SWIGRUBY)
3 #  %rename("to_s") string();
4 ##endif
5 ##if defined(SWIGPYTHON)
6 #  %rename("__str__") string();
7 ##endif
8 #
9
10 %module solv
11
12 %typemap(in) Queue {
13   /* Check if is a list */
14   queue_init(&$1);
15   if (PyList_Check($input)) {
16     int size = PyList_Size($input);
17     int i = 0;
18     for (i = 0; i < size; i++) {
19       PyObject *o = PyList_GetItem($input,i);
20       int v;
21       int e = SWIG_AsVal_int(o, &v);
22       if (!SWIG_IsOK(e)) {
23         SWIG_exception_fail(SWIG_ArgError(e), "list must contain only integers");
24         queue_free(&$1);
25         return NULL;
26       }
27       queue_push(&$1, v);
28     }
29   } else {
30     PyErr_SetString(PyExc_TypeError,"not a list");
31     return NULL;
32   }
33 }
34 %typemap(out) Queue {
35   int i;
36   PyObject *o = PyList_New($1.count);
37   for (i = 0; i < $1.count; i++)
38     PyList_SetItem(o, i, SWIG_From_int($1.elements[i]));
39   queue_free(&$1);
40   $result = o;
41 }
42 %typemap(arginit) Queue {
43   queue_init(&$1);
44 }
45 %typemap(freearg) Queue {
46   queue_free(&$1);
47 }
48
49
50 %include "cdata.i"
51 %include "file.i"
52 %include "typemaps.i"
53
54 %{
55 #include "stdio.h"
56 #include "pool.h"
57 #include "solver.h"
58 #include "policy.h"
59 #include "solverdebug.h"
60 #include "repo_solv.h"
61 #include "chksum.h"
62
63 #include "repo_rpmdb.h"
64 #include "repo_rpmmd.h"
65 #include "repo_write.h"
66 #include "repo_products.h"
67 #include "repo_susetags.h"
68 #include "repo_updateinfoxml.h"
69 #include "repo_deltainfoxml.h"
70 #include "repo_repomdxml.h"
71 #include "repo_content.h"
72 #include "sat_xfopen.h"
73
74 #define true 1
75 #define false 1
76
77 #define SOLVER_SOLUTION_DEINSTALL -100
78 #define SOLVER_SOLUTION_REPLACE -101
79 typedef struct chksum Chksum;
80 typedef int bool;
81
82 typedef struct {
83   Pool* pool;
84   Id id;
85 } XSolvable;
86
87 typedef struct {
88   Solver* solv;
89   Id id;
90 } XRule;
91
92 typedef struct {
93   Repo* repo;
94   Id id;
95 } XRepodata;
96
97 typedef struct {
98   Pool *pool;
99   Id id;
100 } Pool_solvable_iterator;
101
102 typedef struct {
103   Pool *pool;
104   Id id;
105 } Pool_repo_iterator;
106
107 typedef struct {
108   Repo *repo;
109   Id id;
110 } Repo_solvable_iterator;
111
112 typedef struct {
113   Pool *pool;
114   Id how;
115   Id what;
116 } Job;
117
118 typedef struct {
119   Solver *solv;
120   Id id;
121 } Problem;
122
123 typedef struct {
124   Solver *solv;
125   Id problemid;
126   Id id;
127 } Solution;
128
129 typedef struct {
130   Solver *solv;
131   Id problemid;
132   Id solutionid;
133   Id id;
134
135   Id type;
136   Id p;
137   Id rp;
138 } Solutionelement;
139
140 %}
141
142 typedef int Id;
143
144 %include "knownid.h"
145
146 # from repodata.h
147 %constant Id SOLVID_META;
148 %constant Id SOLVID_POS;
149
150 %constant int REL_EQ;
151 %constant int REL_GT;
152 %constant int REL_LT;
153 %constant int REL_ARCH;
154
155
156 typedef struct {
157   Pool* const pool;
158   Id const id;
159 } XSolvable;
160
161 typedef struct {
162   Solver* const solv;
163   Id const id;
164 } XRule;
165
166 typedef struct {
167   Repo* const repo;
168   Id const id;
169 } XRepodata;
170
171 # put before pool/repo so we can access the constructor
172 %nodefaultctor Dataiterator;
173 %nodefaultdtor Dataiterator;
174 typedef struct _Dataiterator {
175   Pool * const pool;
176   Repo * const repo;
177   const Id solvid;
178 } Dataiterator;
179
180 typedef struct {
181   Pool * const pool;
182   Id how;
183   Id what;
184 } Job;
185
186 %nodefaultctor Pool;
187 %nodefaultdtor Pool;
188 typedef struct {
189 } Pool;
190
191 %nodefaultctor Repo;
192 %nodefaultdtor Repo;
193 typedef struct _Repo {
194   Pool * const pool;
195   const char * const name;
196   int priority;
197   int subpriority;
198   int const nsolvables;
199 #if defined(SWIGRUBY)
200   VALUE appdata;
201 #endif
202 #if defined(SWIGPERL)
203   SV *appdata;
204 #endif
205 } Repo;
206
207 %nodefaultctor Pool_solvable_iterator;
208 typedef struct {} Pool_solvable_iterator;
209
210 %nodefaultctor Pool_repo_iterator;
211 typedef struct {} Pool_repo_iterator;
212
213 %nodefaultctor Repo_solvable_iterator;
214 typedef struct {} Repo_solvable_iterator;
215
216 %nodefaultctor Solver;
217 %nodefaultdtor Solver;
218 typedef struct {
219   Pool * const pool;
220   bool ignorealreadyrecommended;
221   bool dosplitprovides;
222   bool fixsystem;
223   bool allowuninstall;
224   bool distupgrade;
225   bool allowdowngrade;
226   bool allowarchchange;
227   bool allowvendorchange;
228 } Solver;
229
230 typedef struct chksum {
231 } Chksum;
232
233 %rename(xfopen) sat_xfopen;
234 %rename(xfopen_fd) sat_xfopen_fd;
235 %rename(xfclose) sat_xfclose;
236 %rename(xfileno) sat_xfileno;
237
238 FILE *sat_xfopen(const char *fn);
239 FILE *sat_xfopen_fd(const char *fn, int fd);
240 %inline {
241   int sat_xfclose(FILE *fp) {
242     return fclose(fp);
243   }
244   int sat_xfileno(FILE *fp) {
245     return fileno(fp);
246   }
247 }
248
249 typedef struct {
250   Solver * const solv;
251   Id const id;
252 } Problem;
253
254 typedef struct {
255   Solver * const solv;
256   Id const problemid;
257   Id const id;
258 } Solution;
259
260 typedef struct {
261   Solver *const solv;
262   Id const problemid;
263   Id const solutionid;
264   Id const id;
265   Id const type;
266 } Solutionelement;
267
268 %nodefaultctor Transaction;
269 %nodefaultdtor Transaction;
270 typedef struct {
271   Pool * const pool;
272 } Transaction;
273
274
275
276 %extend Job {
277   static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
278   static const Id SOLVER_SOLVABLE_NAME = SOLVER_SOLVABLE_NAME;
279   static const Id SOLVER_SOLVABLE_PROVIDES = SOLVER_SOLVABLE_PROVIDES;
280   static const Id SOLVER_SOLVABLE_ONE_OF = SOLVER_SOLVABLE_ONE_OF;
281   static const Id SOLVER_SOLVABLE_REPO = SOLVER_SOLVABLE_REPO;
282   static const Id SOLVER_SOLVABLE_ALL = SOLVER_SOLVABLE_ALL;
283   static const Id SOLVER_SELECTMASK = SOLVER_SELECTMASK;
284   static const Id SOLVER_NOOP = SOLVER_NOOP;
285   static const Id SOLVER_INSTALL = SOLVER_INSTALL;
286   static const Id SOLVER_ERASE = SOLVER_ERASE;
287   static const Id SOLVER_UPDATE = SOLVER_UPDATE;
288   static const Id SOLVER_WEAKENDEPS = SOLVER_WEAKENDEPS;
289   static const Id SOLVER_NOOBSOLETES = SOLVER_NOOBSOLETES;
290   static const Id SOLVER_LOCK = SOLVER_LOCK;
291   static const Id SOLVER_DISTUPGRADE = SOLVER_DISTUPGRADE;
292   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
293   static const Id SOLVER_DROP_ORPHANED = SOLVER_DROP_ORPHANED;
294   static const Id SOLVER_USERINSTALLED = SOLVER_USERINSTALLED;
295   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
296   static const Id SOLVER_WEAK = SOLVER_WEAK;
297   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
298   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
299   static const Id SOLVER_SETEV = SOLVER_SETEV;
300   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
301   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
302   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
303   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
304   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
305   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
306
307   Job(Pool *pool, Id how, Id what) {
308     Job *job = sat_calloc(1, sizeof(*job));
309     job->pool = pool;
310     job->how = how;
311     job->what = what;
312     return job;
313   }
314
315   const char *str() {
316     Pool *pool = $self->pool;
317     Id select = $self->how & SOLVER_SELECTMASK;
318     char *strstart = 0, *strend = 0;
319     switch ($self->how & SOLVER_JOBMASK) {
320       case SOLVER_INSTALL:
321         if (select == SOLVER_SOLVABLE && pool->installed && pool->solvables[$self->what].repo == pool->installed)
322           strstart = "keep ", strend = "installed";
323         else if (select == SOLVER_SOLVABLE_PROVIDES)
324           strstart = "install a solvable ";
325         else
326           strstart = "install ";
327         break;
328       case SOLVER_ERASE:
329         if (select == SOLVER_SOLVABLE && !(pool->installed && pool->solvables[$self->what].repo == pool->installed))
330           strstart = "keep ", strend = "uninstalled";
331         else if (select == SOLVER_SOLVABLE_PROVIDES)
332           strstart = "deinstall all solvables ";
333         else
334           strstart = "deinstall ";
335         break;
336       case SOLVER_UPDATE:
337         strstart = "install the most recent version of ";
338         break;
339       case SOLVER_LOCK:
340         strstart = "lock ";
341         break;
342       default:
343         return "unknwon job";
344     }
345     return pool_tmpjoin(pool, strstart, solver_select2str(pool, select, $self->what), strend);
346   }
347 }
348
349 %extend Chksum {
350   Chksum(Id type) {
351     return (Chksum *)sat_chksum_create(type);
352   }
353   Chksum(Id type, const char *hex) {
354     unsigned char buf[64];
355     int l = sat_chksum_len(type);
356     if (!l)
357       return 0;
358     if (sat_hex2bin(&hex, buf, sizeof(buf)) != l || hex[0])
359       return 0;
360     return (Chksum *)sat_chksum_create_from_bin(type, buf);
361   }
362   ~Chksum() {
363     sat_chksum_free($self, 0);
364   }
365   Id const type;
366   %{
367   SWIGINTERN Id Chksum_type_get(Chksum *chksum) {
368     return sat_chksum_get_type(chksum);
369   }
370   %}
371   void add(const char *str) {
372     sat_chksum_add($self, str, strlen((char *)str));
373   }
374   void add_fp(FILE *fp) {
375     char buf[4096];
376     int l;
377     while ((l = fread(buf, 1, sizeof(buf), fp)) > 0)
378       sat_chksum_add($self, buf, l);
379     rewind(fp);         /* convenience */
380   }
381   void add_fd(int fd) {
382     char buf[4096];
383     int l;
384     while ((l = read(fd, buf, sizeof(buf))) > 0)
385       sat_chksum_add($self, buf, l);
386     lseek(fd, 0, 0);    /* convenience */
387   }
388   void add_stat(const char *filename) {
389     struct stat stb;
390     if (stat(filename, &stb))
391       memset(&stb, 0, sizeof(stb));
392     sat_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
393     sat_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
394     sat_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
395     sat_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
396   }
397   bool matches(Chksum *othersum) {
398     int l;
399     const unsigned char *b, *bo;
400     if (!othersum)
401       return 0;
402     if (sat_chksum_get_type($self) != sat_chksum_get_type(othersum))
403       return 0;
404     b = sat_chksum_get($self, &l);
405     bo = sat_chksum_get(othersum, 0);
406     return memcmp(b, bo, l) == 0;
407   }
408   SWIGCDATA raw() {
409     int l;
410     const unsigned char *b;
411     b = sat_chksum_get($self, &l);
412     return cdata_void((void *)b, l);
413   }
414   %newobject hex;
415   char *hex() {
416     int l;
417     const unsigned char *b;
418     char *ret, *rp;
419
420     b = sat_chksum_get($self, &l);
421     ret = sat_malloc(2 * l + 1);
422     sat_bin2hex(b, l, ret);
423     return ret;
424   }
425 }
426
427
428
429 %extend Pool {
430   Pool() {
431     Pool *pool = pool_create();
432     return pool;
433   }
434   ~Pool() {
435   }
436   void set_debuglevel(int level) {
437     pool_setdebuglevel($self, level);
438   }
439 #if defined(SWIGPYTHON)
440   %{
441   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
442     XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
443     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
444     PyObject *result = PyEval_CallObject((PyObject *)d, args);
445     if (!result)
446       return 0; /* exception */
447     int ecode = 0;
448     int vresult = 0;
449     Py_DECREF(args);
450     ecode = SWIG_AsVal_int(result, &vresult);
451     Py_DECREF(result);
452     return SWIG_IsOK(ecode) ? vresult : 0;
453   }
454   %}
455   void set_loadcallback(PyObject *callable) {
456     if (!callable) {
457       if ($self->loadcallback == loadcallback) {
458         Py_DECREF($self->loadcallbackdata);
459         pool_setloadcallback($self, 0, 0);
460       }
461       return;
462     }
463     Py_INCREF(callable);
464     pool_setloadcallback($self, loadcallback, callable);
465   }
466 #endif
467   void free() {
468 #if defined(SWIGPYTHON)
469     Pool_set_loadcallback($self, 0);
470 #endif
471     pool_free($self);
472   }
473   Id str2id(const char *str, int create=1) {
474     return str2id($self, str, create);
475   }
476   const char *id2str(Id id) {
477     return id2str($self, id);
478   }
479   const char *dep2str(Id id) {
480     return dep2str($self, id);
481   }
482   Id rel2id(Id name, Id evr, int flags, int create=1) {
483     return rel2id($self, name, evr, flags, create);
484   }
485   Id id2langid(Id id, const char *lang, int create=1) {
486     return pool_id2langid($self, id, lang, create);
487   }
488   void setarch(const char *arch) {
489     pool_setarch($self, arch);
490   }
491   Repo *add_repo(const char *name) {
492     return repo_create($self, name);
493   }
494   const char *lookup_str(Id entry, Id keyname) {
495     return pool_lookup_str($self, entry, keyname);
496   }
497   Id lookup_id(Id entry, Id keyname) {
498     return pool_lookup_id($self, entry, keyname);
499   }
500   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
501     return pool_lookup_num($self, entry, keyname, notfound);
502   }
503   bool lookup_void(Id entry, Id keyname) {
504     return pool_lookup_void($self, entry, keyname);
505   }
506   %newobject lookup_checksum;
507   Chksum *lookup_checksum(Id entry, Id keyname) {
508     Id type = 0;
509     const unsigned char *b = pool_lookup_bin_checksum($self, entry, keyname, &type);
510     return sat_chksum_create_from_bin(type, b);
511   }
512   %newobject dataiterator_new;
513   Dataiterator *dataiterator_new(Id p, Id key,  const char *match, int flags) {
514     return new_Dataiterator($self, 0, p, key, match, flags);
515   }
516   const char *solvid2str(Id solvid) {
517     return solvid2str($self, solvid);
518   }
519   void addfileprovides() {
520     pool_addfileprovides($self);
521   }
522   Queue addfileprovides_ids() {
523     Queue r;
524     Id *addedfileprovides = 0;
525     queue_init(&r);
526     pool_addfileprovides_ids($self, $self->installed, &addedfileprovides);
527     if (addedfileprovides) {
528       for (; *addedfileprovides; addedfileprovides++)
529         queue_push(&r, *addedfileprovides);
530     }
531     return r;
532   }
533   void createwhatprovides() {
534     pool_createwhatprovides($self);
535   }
536   %newobject solvables;
537   Pool_solvable_iterator * const solvables;
538   %{
539   SWIGINTERN Pool_solvable_iterator * Pool_solvables_get(Pool *pool) {
540     Pool_solvable_iterator *s;
541     s = sat_calloc(1, sizeof(*s));
542     s->pool = pool;
543     s->id = 0;
544     return s;
545   }
546   %}
547   %newobject repos;
548   Pool_repo_iterator * const repos;
549   %{
550   SWIGINTERN Pool_repo_iterator * Pool_repos_get(Pool *pool) {
551     Pool_repo_iterator *s;
552     s = sat_calloc(1, sizeof(*s));
553     s->pool = pool;
554     s->id = 0;
555     return s;
556   }
557   %}
558   Repo *installed;
559   %{
560   SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
561     pool_set_installed(pool, installed);
562   }
563   Repo *Pool_installed_get(Pool *pool) {
564     return pool->installed;
565   }
566   %}
567
568   Queue providerids(Id dep) {
569     Pool *pool = $self;
570     Queue q;
571     Id p, pp;
572     queue_init(&q);
573     FOR_PROVIDES(p, pp, dep)
574       queue_push(&q, p);
575     return q;
576   }
577   Queue allprovidingids() {
578     Pool *pool = $self;
579     Queue q;
580     Id id;
581     queue_init(&q);
582     for (id = 1; id < pool->ss.nstrings; id++)
583       if (pool->whatprovides[id])
584         queue_push(&q, id);
585     return q;
586   }
587   # move to job?
588   Queue jobsolvids(Job *job) {
589     Pool *pool = $self;
590     Id p, pp, how;
591     Queue q;
592     queue_init(&q);
593     how = job->how & SOLVER_SELECTMASK;
594     FOR_JOB_SELECT(p, pp, how, job->what)
595       queue_push(&q, p);
596     return q;
597   }
598   Job *Job(Id how, Id what) {
599     return new_Job($self, how, what);
600   }
601
602 #if defined(SWIGPYTHON)
603   %pythoncode {
604     def jobsolvables (self, *args):
605       return [ self.solvables[id] for id in self.jobsolvids(*args) ]
606     def providers(self, *args):
607       return [ self.solvables[id] for id in self.providerids(*args) ]
608   }
609 #endif
610
611   Id towhatprovides(Queue q) {
612     return pool_queuetowhatprovides($self, &q);
613   }
614   bool isknownarch(Id id) {
615     Pool *pool = $self;
616     if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
617       return 1;
618     if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
619       return 0;
620     return 1;
621   }
622
623   %newobject create_solver;
624   Solver *create_solver() {
625     return solver_create($self);
626   }
627 }
628
629 %extend Repo {
630   static const int REPO_REUSE_REPODATA = REPO_REUSE_REPODATA;
631   static const int REPO_NO_INTERNALIZE = REPO_NO_INTERNALIZE;
632   static const int REPO_LOCALPOOL = REPO_LOCALPOOL;
633   static const int REPO_USE_LOADING = REPO_USE_LOADING;
634   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
635   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
636   static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES; /* repo_susetags */
637   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS ; /* repo_solv */
638
639   void free(int reuseids = 0) {
640     repo_free($self, reuseids);
641   }
642   void empty(int reuseids = 0) {
643     repo_empty($self, reuseids);
644   }
645   bool add_solv(const char *name, int flags = 0) {
646     FILE *fp = fopen(name, "r");
647     if (!fp)
648       return 0;
649     int r = repo_add_solv_flags($self, fp, flags);
650     fclose(fp);
651     return r == 0;
652   }
653   bool add_solv(FILE *fp, int flags = 0) {
654     return repo_add_solv_flags($self, fp, flags) == 0;
655   }
656   bool add_products(const char *proddir, int flags = 0) {
657     repo_add_products($self, proddir, 0, flags);
658     return 1;
659   }
660   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
661     repo_add_rpmmd($self, fp, language, flags);
662     return 1;
663   }
664   bool add_rpmdb(Repo *ref, int flags = 0) {
665     repo_add_rpmdb($self, ref, 0, flags);
666     return 1;
667   }
668   Id add_rpm(const char *name, int flags = 0) {
669     return repo_add_rpm($self, name, flags);
670   }
671   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
672     repo_add_susetags($self, fp, defvendor, language, flags);
673     return 1;
674   }
675   bool add_repomdxml(FILE *fp, int flags = 0) {
676     repo_add_repomdxml($self, fp, flags);
677     return 1;
678   }
679   bool add_content(FILE *fp, int flags = 0) {
680     repo_add_content($self, fp, flags);
681     return 1;
682   }
683   bool add_updateinfoxml(FILE *fp, int flags = 0) {
684     repo_add_updateinfoxml($self, fp, flags);
685     return 1;
686   }
687   bool add_deltainfoxml(FILE *fp, int flags = 0) {
688     repo_add_deltainfoxml($self, fp, flags);
689     return 1;
690   }
691   void internalize() {
692     repo_internalize($self);
693   }
694   const char *lookup_str(Id entry, Id keyname) {
695     return repo_lookup_str($self, entry, keyname);
696   }
697   Id lookup_id(Id entry, Id keyname) {
698     return repo_lookup_id($self, entry, keyname);
699   }
700   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
701     return repo_lookup_num($self, entry, keyname, notfound);
702   }
703   void write(FILE *fp) {
704     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
705   }
706   # HACK, remove if no longer needed!
707   bool write_first_repodata(FILE *fp, int flags = 0) {
708     int oldnrepodata = $self->nrepodata;
709     $self->nrepodata = 1;
710     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
711     $self->nrepodata = oldnrepodata;
712     return 1;
713   }
714   %newobject dataiterator_new;
715   Dataiterator *dataiterator_new(Id p, Id key,  const char *match, int flags) {
716     return new_Dataiterator($self->pool, $self, p, key, match, flags);
717   }
718
719   Id const id;
720   %{
721   SWIGINTERN Id Repo_id_get(Repo *repo) {
722     return repo->repoid;
723   }
724   %}
725   Repo_solvable_iterator * const solvables;
726   %{
727   SWIGINTERN Repo_solvable_iterator * Repo_solvables_get(Repo *repo) {
728     Repo_solvable_iterator *s;
729     s = sat_calloc(1, sizeof(*s));
730     s->repo = repo;
731     s->id = 0;
732     return s;
733   }
734   %}
735
736   XRepodata *add_repodata(int flags = 0) {
737     Repodata *rd = repo_add_repodata($self, flags);
738     return new_XRepodata($self, rd - $self->repodata);
739   }
740
741   void create_stubs() {
742     Repodata *data;
743     if (!$self->nrepodata)
744       return;
745     data = $self->repodata  + ($self->nrepodata - 1);
746     if (data->state != REPODATA_STUB)
747       repodata_create_stubs(data);
748   }
749 #if defined(SWIGPYTHON)
750   PyObject *appdata;
751   %{
752   SWIGINTERN void Repo_appdata_set(Repo *repo, PyObject *o) {
753     repo->appdata = o;
754   }
755   SWIGINTERN PyObject *Repo_appdata_get(Repo *repo) {
756     PyObject *o = repo->appdata;
757     Py_INCREF(o);
758     return o;
759   }
760   %}
761 #endif
762   bool iscontiguous() {
763     int i;
764     for (i = $self->start; i < $self->end; i++)
765       if ($self->pool->solvables[i].repo != $self)
766         return 0;
767     return 1;
768   }
769   XRepodata *first_repodata() {
770      int i;
771      if (!$self->nrepodata)
772        return 0;
773      /* make sure all repodatas but the first are extensions */
774      if ($self->repodata[0].loadcallback)
775         return 0;
776      for (i = 1; i < $self->nrepodata; i++)
777        if (!$self->repodata[i].loadcallback)
778          return 0;       /* oops, not an extension */
779      return new_XRepodata($self, 0);
780    }
781 }
782
783 %extend Dataiterator {
784   static const int SEARCH_STRING = SEARCH_STRING;
785   static const int SEARCH_SUBSTRING = SEARCH_SUBSTRING;
786   static const int SEARCH_GLOB = SEARCH_GLOB;
787   static const int SEARCH_REGEX = SEARCH_REGEX;
788   static const int SEARCH_NOCASE = SEARCH_NOCASE;
789   static const int SEARCH_FILES = SEARCH_FILES;
790   static const int SEARCH_COMPLETE_FILELIST = SEARCH_COMPLETE_FILELIST;
791
792   Dataiterator(Pool *pool, Repo *repo, Id p, Id key, const char *match, int flags) {
793     Dataiterator *di = sat_calloc(1, sizeof(*di));
794     dataiterator_init(di, pool, repo, p, key, match, flags);
795     return di;
796   }
797   ~Dataiterator() {
798     dataiterator_free($self);
799     sat_free($self);
800   }
801   %newobject __iter__;
802   Dataiterator *__iter__() {
803     Dataiterator *ndi;
804     ndi = sat_calloc(1, sizeof(*ndi));
805     dataiterator_init_clone(ndi, $self);
806     return ndi;
807   }
808   %exception next {
809     $action
810     if (!result) {
811       PyErr_SetString(PyExc_StopIteration,"no more matches");
812       return NULL;
813     }
814   }
815   %newobject next;
816   Dataiterator *next() {
817     Dataiterator *ndi;
818     if (!dataiterator_step($self)) {
819       return 0;
820     }
821     ndi = sat_calloc(1, sizeof(*ndi));
822     dataiterator_init_clone(ndi, $self);
823     return ndi;
824   }
825   void setpos_parent() {
826     dataiterator_setpos_parent($self);
827   }
828   void prepend_keyname(Id key) {
829     dataiterator_prepend_keyname($self, key);
830   }
831   void skip_solvable() {
832     dataiterator_skip_solvable($self);
833   }
834
835   %newobject solvable;
836   XSolvable * const solvable;
837   %{
838   SWIGINTERN XSolvable *Dataiterator_solvable_get(Dataiterator *di) {
839     return new_XSolvable(di->pool, di->solvid);
840   }
841   %}
842   Id key_id() {
843     return $self->key->name;
844   }
845   const char *key_idstr() {
846     return id2str($self->pool, $self->key->name);
847   }
848   Id keytype_id() {
849     return $self->key->type;
850   }
851   const char *keytype_idstr() {
852     return id2str($self->pool, $self->key->type);
853   }
854   Id match_id() {
855      return $self->kv.id;
856   }
857   const char *match_idstr() {
858      return id2str($self->pool, $self->kv.id);
859   }
860   const char *match_str() {
861      return $self->kv.str;
862   }
863   int match_num() {
864      return $self->kv.num;
865   }
866   int match_num2() {
867      return $self->kv.num2;
868   }
869 }
870
871
872 %extend Pool_solvable_iterator {
873   %newobject __iter__;
874   Pool_solvable_iterator *__iter__() {
875     Pool_solvable_iterator *s;
876     s = sat_calloc(1, sizeof(*s));
877     *s = *$self;
878     return s;
879   }
880   %exception next {
881     $action
882     if (!result) {
883       PyErr_SetString(PyExc_StopIteration,"no more matches");
884       return NULL;
885     }
886   }
887   %newobject next;
888   XSolvable *next() {
889     Pool *pool = $self->pool;
890     XSolvable *s;
891     if ($self->id >= pool->nsolvables)
892       return 0;
893     while (++$self->id < pool->nsolvables)
894       if (pool->solvables[$self->id].repo)
895         return new_XSolvable(pool, $self->id);
896     return 0;
897   }
898   %newobject __getitem__;
899   XSolvable *__getitem__(Id key) {
900     Pool *pool = $self->pool;
901     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo)
902       return new_XSolvable(pool, key);
903     return 0;
904   }
905 }
906
907 %extend Pool_repo_iterator {
908   %newobject __iter__;
909   Pool_repo_iterator *__iter__() {
910     Pool_repo_iterator *s;
911     s = sat_calloc(1, sizeof(*s));
912     *s = *$self;
913     return s;
914   }
915   %exception next {
916     $action
917     if (!result) {
918       PyErr_SetString(PyExc_StopIteration,"no more matches");
919       return NULL;
920     }
921   }
922   Repo *next() {
923     Pool *pool = $self->pool;
924     if ($self->id >= pool->nrepos + 1)
925       return 0;
926     while (++$self->id < pool->nrepos + 1) {
927       Repo *r = pool_id2repo(pool, $self->id);
928       if (r)
929         return r;
930     }
931     return 0;
932   }
933   Repo *__getitem__(Id key) {
934     Pool *pool = $self->pool;
935     if (key > 0 && key < pool->nrepos + 1)
936       return pool_id2repo(pool, key);
937     return 0;
938   }
939 }
940
941 %extend Repo_solvable_iterator {
942   %newobject __iter__;
943   Repo_solvable_iterator *__iter__() {
944     Repo_solvable_iterator *s;
945     s = sat_calloc(1, sizeof(*s));
946     *s = *$self;
947     return s;
948   }
949   %exception next {
950     $action
951     if (!result) {
952       PyErr_SetString(PyExc_StopIteration,"no more matches");
953       return NULL;
954     }
955   }
956   %newobject next;
957   XSolvable *next() {
958     Repo *repo = $self->repo;
959     Pool *pool = repo->pool;
960     XSolvable *s;
961     if (repo->start > 0 && $self->id < repo->start)
962       $self->id = repo->start - 1;
963     if ($self->id >= repo->end)
964       return 0;
965     while (++$self->id < repo->end)
966       if (pool->solvables[$self->id].repo == repo)
967         return new_XSolvable(pool, $self->id);
968     return 0;
969   }
970   %newobject __getitem__;
971   XSolvable *__getitem__(Id key) {
972     Repo *repo = $self->repo;
973     Pool *pool = repo->pool;
974     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo == repo)
975       return new_XSolvable(pool, key);
976     return 0;
977   }
978 }
979
980 %extend XSolvable {
981   XSolvable(Pool *pool, Id id) {
982     if (!id)
983       return 0;
984     XSolvable *s = sat_calloc(1, sizeof(*s));
985     s->pool = pool;
986     s->id = id;
987     return s;
988   }
989   const char *str() {
990     return solvid2str($self->pool, $self->id);
991   }
992   const char *lookup_str(Id keyname) {
993     return pool_lookup_str($self->pool, $self->id, keyname);
994   }
995   Id lookup_id(Id keyname) {
996     return pool_lookup_id($self->pool, $self->id, keyname);
997   }
998   unsigned int lookup_num(Id keyname, unsigned int notfound = 0) {
999     return pool_lookup_num($self->pool, $self->id, keyname, notfound);
1000   }
1001   bool lookup_void(Id keyname) {
1002     return pool_lookup_void($self->pool, $self->id, keyname);
1003   }
1004   %newobject lookup_checksum;
1005   Chksum *lookup_checksum(Id keyname) {
1006     Id type = 0;
1007     const unsigned char *b = pool_lookup_bin_checksum($self->pool, $self->id, keyname, &type);
1008     return sat_chksum_create_from_bin(type, b);
1009   }
1010   const char *lookup_location(int *OUTPUT) {
1011     return solvable_get_location($self->pool->solvables + $self->id, OUTPUT);
1012   }
1013   bool installable() {
1014     return pool_installable($self->pool, pool_id2solvable($self->pool, $self->id));
1015   }
1016   bool isinstalled() {
1017     Pool *pool = $self->pool;
1018     return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed;
1019   }
1020
1021   const char * const name;
1022   %{
1023     SWIGINTERN const char *XSolvable_name_get(XSolvable *xs) {
1024       Pool *pool = xs->pool;
1025       return id2str(pool, pool->solvables[xs->id].name);
1026     }
1027   %}
1028   Id const nameid;
1029   %{
1030     SWIGINTERN Id XSolvable_nameid_get(XSolvable *xs) {
1031       return xs->pool->solvables[xs->id].name;
1032     }
1033   %}
1034   const char * const evr;
1035   %{
1036     SWIGINTERN const char *XSolvable_evr_get(XSolvable *xs) {
1037       Pool *pool = xs->pool;
1038       return id2str(pool, pool->solvables[xs->id].evr);
1039     }
1040   %}
1041   Id const evrid;
1042   %{
1043     SWIGINTERN Id XSolvable_evrid_get(XSolvable *xs) {
1044       return xs->pool->solvables[xs->id].evr;
1045     }
1046   %}
1047   const char * const arch;
1048   %{
1049     SWIGINTERN const char *XSolvable_arch_get(XSolvable *xs) {
1050       Pool *pool = xs->pool;
1051       return id2str(pool, pool->solvables[xs->id].arch);
1052     }
1053   %}
1054   Id const archid;
1055   %{
1056     SWIGINTERN Id XSolvable_archid_get(XSolvable *xs) {
1057       return xs->pool->solvables[xs->id].arch;
1058     }
1059   %}
1060   const char * const vendor;
1061   %{
1062     SWIGINTERN const char *XSolvable_vendor_get(XSolvable *xs) {
1063       Pool *pool = xs->pool;
1064       return id2str(pool, pool->solvables[xs->id].vendor);
1065     }
1066   %}
1067   Id const vendorid;
1068   %{
1069     SWIGINTERN Id XSolvable_vendorid_get(XSolvable *xs) {
1070       return xs->pool->solvables[xs->id].vendor;
1071     }
1072   %}
1073   Repo * const repo;
1074   %{
1075     SWIGINTERN Repo *XSolvable_repo_get(XSolvable *xs) {
1076       return xs->pool->solvables[xs->id].repo;
1077     }
1078   %}
1079 }
1080
1081 %extend Problem {
1082   Problem(Solver *solv, Id id) {
1083     Problem *p;
1084     p = sat_calloc(1, sizeof(*p));
1085     p->solv = solv;
1086     p->id = id;
1087     return p;
1088   }
1089   Id findproblemrule_helper() {
1090     return solver_findproblemrule($self->solv, $self->id);
1091   }
1092   Queue findallproblemrules_helper(int unfiltered=0) {
1093     Solver *solv = $self->solv;
1094     Id probr;
1095     int i, j;
1096     Queue q;
1097     queue_init(&q);
1098     solver_findallproblemrules(solv, $self->id, &q);
1099     if (!unfiltered)
1100       {
1101         for (i = j = 0; i < q.count; i++)
1102           {
1103             probr = q.elements[i];
1104             if ((probr >= solv->updaterules && probr < solv->updaterules_end) || (probr >= solv->jobrules && probr < solv->jobrules_end))
1105               continue;
1106             q.elements[j++] = probr;
1107           }
1108         if (j)
1109           queue_truncate(&q, j);
1110       }
1111     return q;
1112   }
1113   int solution_count() {
1114     return solver_solution_count($self->solv, $self->id);
1115   }
1116 #if defined(SWIGPYTHON)
1117   %pythoncode {
1118     def findproblemrule(self):
1119       return XRule(self.solv, self.findproblemrule_helper())
1120     def findallproblemrules(self, unfiltered=0):
1121       return [ XRule(self.solv, i) for i in self.findallproblemrules_helper(unfiltered) ]
1122     def solutions(self):
1123       return [ Solution(self, i) for i in range(1, self.solution_count() + 1) ];
1124   }
1125 #endif
1126 }
1127
1128 %extend Solution {
1129   Solution(Problem *p, Id id) {
1130     Solution *s;
1131     s = sat_calloc(1, sizeof(*s));
1132     s->solv = p->solv;
1133     s->problemid = p->id;
1134     s->id = id;
1135     return s;
1136   }
1137   int element_count() {
1138     return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
1139   }
1140 #if defined(SWIGPYTHON)
1141   %pythoncode {
1142     def elements(self):
1143       return [ Solutionelement(self, i) for i in range(1, self.element_count() + 1) ];
1144   }
1145 #endif
1146 }
1147
1148 %extend Solutionelement {
1149   Solutionelement(Solution *s, Id id) {
1150     Solutionelement *e;
1151     e = sat_calloc(1, sizeof(*e));
1152     e->solv = s->solv;
1153     e->problemid = s->problemid;
1154     e->solutionid = s->id;
1155     e->id = id;
1156     solver_next_solutionelement(e->solv, e->problemid, e->solutionid, e->id - 1, &e->p, &e->rp);
1157     if (e->p > 0) {
1158       e->type = e->rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_DEINSTALL;
1159     } else {
1160       e->type = e->p;
1161       e->p = e->rp;
1162       e->rp = 0;
1163     }
1164     return e;
1165   }
1166   int illegalreplace() {
1167     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
1168       return 0;
1169     return policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
1170   }
1171   %newobject solvable;
1172   XSolvable * const solvable;
1173   %newobject replacement;
1174   XSolvable * const replacement;
1175   int const jobidx;
1176   %{
1177     SWIGINTERN XSolvable *Solutionelement_solvable_get(Solutionelement *e) {
1178       return new_XSolvable(e->solv->pool, e->p);
1179     }
1180     SWIGINTERN XSolvable *Solutionelement_replacement_get(Solutionelement *e) {
1181       return new_XSolvable(e->solv->pool, e->rp);
1182     }
1183     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
1184       return (e->p - 1) / 2;
1185     }
1186   %}
1187 }
1188
1189 %extend Solver {
1190   static const int SOLVER_RULE_UNKNOWN = SOLVER_RULE_UNKNOWN;
1191   static const int SOLVER_RULE_RPM = SOLVER_RULE_RPM;
1192   static const int SOLVER_RULE_RPM_NOT_INSTALLABLE = SOLVER_RULE_RPM_NOT_INSTALLABLE;
1193   static const int SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP = SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP;
1194   static const int SOLVER_RULE_RPM_PACKAGE_REQUIRES = SOLVER_RULE_RPM_PACKAGE_REQUIRES;
1195   static const int SOLVER_RULE_RPM_SELF_CONFLICT = SOLVER_RULE_RPM_SELF_CONFLICT;
1196   static const int SOLVER_RULE_RPM_PACKAGE_CONFLICT = SOLVER_RULE_RPM_PACKAGE_CONFLICT;
1197   static const int SOLVER_RULE_RPM_SAME_NAME = SOLVER_RULE_RPM_SAME_NAME;
1198   static const int SOLVER_RULE_RPM_PACKAGE_OBSOLETES = SOLVER_RULE_RPM_PACKAGE_OBSOLETES;
1199   static const int SOLVER_RULE_RPM_IMPLICIT_OBSOLETES = SOLVER_RULE_RPM_IMPLICIT_OBSOLETES;
1200   static const int SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES = SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES;
1201   static const int SOLVER_RULE_UPDATE = SOLVER_RULE_UPDATE;
1202   static const int SOLVER_RULE_FEATURE = SOLVER_RULE_FEATURE;
1203   static const int SOLVER_RULE_JOB = SOLVER_RULE_JOB;
1204   static const int SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP = SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP;
1205   static const int SOLVER_RULE_DISTUPGRADE = SOLVER_RULE_DISTUPGRADE;
1206   static const int SOLVER_RULE_INFARCH = SOLVER_RULE_INFARCH;
1207   static const int SOLVER_RULE_CHOICE = SOLVER_RULE_CHOICE;
1208   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
1209
1210   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
1211   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
1212   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
1213   static const int SOLVER_SOLUTION_DEINSTALL = SOLVER_SOLUTION_DEINSTALL;
1214   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
1215
1216   static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE;
1217   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
1218   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
1219
1220   ~Solver() {
1221     solver_free($self);
1222   }
1223 #if defined(SWIGPYTHON)
1224   %pythoncode {
1225     def solve(self, jobs):
1226       j = []
1227       for job in jobs: j += [job.how, job.what]
1228       nprob = self.solve_helper(j)
1229       return [ Problem(self, pid) for pid in range(1, nprob + 1) ]
1230   }
1231 #endif
1232   int solve_helper(Queue jobs) {
1233     solver_solve($self, &jobs);
1234     return solver_problem_count($self);
1235   }
1236   %newobject transaction;
1237   Transaction *transaction() {
1238     Transaction *t;
1239     t = sat_calloc(1, sizeof(*t));
1240     transaction_init_clone(t, &$self->trans);
1241     return t;
1242   }
1243 }
1244
1245 %extend Transaction {
1246   static const int SOLVER_TRANSACTION_IGNORE = SOLVER_TRANSACTION_IGNORE;
1247   static const int SOLVER_TRANSACTION_ERASE = SOLVER_TRANSACTION_ERASE;
1248   static const int SOLVER_TRANSACTION_REINSTALLED = SOLVER_TRANSACTION_REINSTALLED;
1249   static const int SOLVER_TRANSACTION_DOWNGRADED = SOLVER_TRANSACTION_DOWNGRADED;
1250   static const int SOLVER_TRANSACTION_CHANGED = SOLVER_TRANSACTION_CHANGED;
1251   static const int SOLVER_TRANSACTION_UPGRADED = SOLVER_TRANSACTION_UPGRADED;
1252   static const int SOLVER_TRANSACTION_OBSOLETED = SOLVER_TRANSACTION_OBSOLETED;
1253   static const int SOLVER_TRANSACTION_INSTALL = SOLVER_TRANSACTION_INSTALL;
1254   static const int SOLVER_TRANSACTION_REINSTALL = SOLVER_TRANSACTION_REINSTALL;
1255   static const int SOLVER_TRANSACTION_DOWNGRADE = SOLVER_TRANSACTION_DOWNGRADE;
1256   static const int SOLVER_TRANSACTION_CHANGE = SOLVER_TRANSACTION_CHANGE;
1257   static const int SOLVER_TRANSACTION_UPGRADE = SOLVER_TRANSACTION_UPGRADE;
1258   static const int SOLVER_TRANSACTION_OBSOLETES = SOLVER_TRANSACTION_OBSOLETES;
1259   static const int SOLVER_TRANSACTION_MULTIINSTALL = SOLVER_TRANSACTION_MULTIINSTALL;
1260   static const int SOLVER_TRANSACTION_MULTIREINSTALL = SOLVER_TRANSACTION_MULTIREINSTALL;
1261   static const int SOLVER_TRANSACTION_MAXTYPE = SOLVER_TRANSACTION_MAXTYPE;
1262   static const int SOLVER_TRANSACTION_SHOW_ACTIVE = SOLVER_TRANSACTION_SHOW_ACTIVE;
1263   static const int SOLVER_TRANSACTION_SHOW_ALL = SOLVER_TRANSACTION_SHOW_ALL;
1264   static const int SOLVER_TRANSACTION_SHOW_OBSOLETES = SOLVER_TRANSACTION_SHOW_OBSOLETES;
1265   static const int SOLVER_TRANSACTION_SHOW_MULTIINSTALL = SOLVER_TRANSACTION_SHOW_MULTIINSTALL;
1266   static const int SOLVER_TRANSACTION_CHANGE_IS_REINSTALL = SOLVER_TRANSACTION_CHANGE_IS_REINSTALL;
1267   static const int SOLVER_TRANSACTION_MERGE_VENDORCHANGES = SOLVER_TRANSACTION_MERGE_VENDORCHANGES;
1268   static const int SOLVER_TRANSACTION_MERGE_ARCHCHANGES = SOLVER_TRANSACTION_MERGE_ARCHCHANGES;
1269   static const int SOLVER_TRANSACTION_RPM_ONLY = SOLVER_TRANSACTION_RPM_ONLY;
1270   static const int SOLVER_TRANSACTION_ARCHCHANGE = SOLVER_TRANSACTION_ARCHCHANGE;
1271   static const int SOLVER_TRANSACTION_VENDORCHANGE = SOLVER_TRANSACTION_VENDORCHANGE;
1272   static const int SOLVER_TRANSACTION_KEEP_ORDERDATA = SOLVER_TRANSACTION_KEEP_ORDERDATA;
1273   ~Transaction() {
1274     transaction_free($self);
1275     sat_free($self);
1276   }
1277   bool isempty() {
1278     return $self->steps.count == 0;
1279   }
1280   Queue classify_helper(int mode) {
1281     Queue q;
1282     queue_init(&q);
1283     transaction_classify($self, mode, &q);
1284     return q;
1285   }
1286   Queue classify_pkgs_helper(int mode, Id cl, Id from, Id to) {
1287     Queue q;
1288     queue_init(&q);
1289     transaction_classify_pkgs($self, mode, cl, from, to, &q);
1290     return q;
1291   }
1292   %newobject othersolvable;
1293   XSolvable *othersolvable(XSolvable *s) {
1294     Id op = transaction_obs_pkg($self, s->id);
1295     return new_XSolvable($self->pool, op);
1296   }
1297 #if defined(SWIGPYTHON)
1298   %pythoncode {
1299     def classify(self, mode = 0):
1300       r = []
1301       cr = self.classify_helper(mode)
1302       for type, cnt, fromid, toid in zip(*([iter(cr)] * 4)):
1303         if type != self.SOLVER_TRANSACTION_IGNORE:
1304           r.append([ type, [ self.pool.solvables[j] for j in self.classify_pkgs_helper(mode, type, fromid, toid) ], fromid, toid ])
1305       return r
1306     }
1307 #endif
1308   Queue installedresult_helper(int *OUTPUT) {
1309     Queue q;
1310     queue_init(&q);
1311     *OUTPUT = transaction_installedresult(self, &q);
1312     return q;
1313   }
1314 #if defined(SWIGPYTHON)
1315   %pythoncode {
1316     def installedresult(self):
1317       r = self.installedresult_helper()
1318       newpkgs = r.pop()
1319       rn = [ self.pool.solvables[r[i]] for i in range(0, newpkgs) ]
1320       rk = [ self.pool.solvables[r[i]] for i in range(newpkgs, len(r)) ]
1321       return rn, rk
1322   }
1323 #endif
1324   Queue steps_helper() {
1325     Queue q;
1326     queue_init_clone(&q, &$self->steps);
1327     return q;
1328   }
1329   int steptype(XSolvable *s, int mode) {
1330     return transaction_type($self, s->id, mode);
1331   }
1332 #if defined(SWIGPYTHON)
1333   %pythoncode {
1334     def steps(self):
1335       return [ self.pool.solvables[i] for i in self.steps_helper() ]
1336   }
1337 #endif
1338   int calc_installsizechange() {
1339     return transaction_calc_installsizechange($self);
1340   }
1341 }
1342
1343 %extend XRule {
1344   XRule(Solver *solv, Id id) {
1345     if (!id)
1346       return 0;
1347     XRule *xr = sat_calloc(1, sizeof(*xr));
1348     xr->solv = solv;
1349     xr->id = id;
1350     return xr;
1351   }
1352   %apply Id *OUTPUT { Id *source, Id *target, Id *dep };
1353   int info_helper(Id *source, Id *target, Id *dep) {
1354     return solver_ruleinfo($self->solv, $self->id, source, target, dep);
1355   }
1356 #if defined(SWIGPYTHON)
1357   %pythoncode {
1358     def info(self):
1359       type, source, target, dep = self.info_helper()
1360       if source:
1361           source = self.solv.pool.solvables[source]
1362       if target:
1363           target = self.solv.pool.solvables[target]
1364       return type, source, target, dep
1365   }
1366 #endif
1367 }
1368
1369
1370 %extend XRepodata {
1371   XRepodata(Repo *repo, Id id) {
1372     XRepodata *xr = sat_calloc(1, sizeof(*xr));
1373     xr->repo = repo;
1374     xr->id = id;
1375     return xr;
1376   }
1377   Id new_handle() {
1378     return repodata_new_handle($self->repo->repodata + $self->id);
1379   }
1380   void set_id(Id solvid, Id keyname, Id id) {
1381     repodata_set_id($self->repo->repodata + $self->id, solvid, keyname, id);
1382   }
1383   void set_str(Id solvid, Id keyname, const char *str) {
1384     repodata_set_str($self->repo->repodata + $self->id, solvid, keyname, str);
1385   }
1386   void set_poolstr(Id solvid, Id keyname, const char *str) {
1387     repodata_set_poolstr($self->repo->repodata + $self->id, solvid, keyname, str);
1388   }
1389   void add_idarray(Id solvid, Id keyname, Id id) {
1390     repodata_add_idarray($self->repo->repodata + $self->id, solvid, keyname, id);
1391   }
1392   void add_flexarray(Id solvid, Id keyname, Id handle) {
1393     repodata_add_flexarray($self->repo->repodata + $self->id, solvid, keyname, handle);
1394   }
1395   void set_bin_checksum(Id solvid, Id keyname, Chksum *chksum) {
1396     const unsigned char *buf = sat_chksum_get(chksum, 0);
1397     if (buf)
1398       repodata_set_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, sat_chksum_get_type(chksum), buf);
1399   }
1400   const char *lookup_str(Id solvid, Id keyname) {
1401     return repodata_lookup_str($self->repo->repodata + $self->id, solvid, keyname);
1402   }
1403   Queue lookup_idarray(Id solvid, Id keyname) {
1404     Queue r;
1405     queue_init(&r);
1406     repodata_lookup_idarray($self->repo->repodata + $self->id, solvid, keyname, &r);
1407     return r;
1408   }
1409   %newobject lookup_checksum;
1410   Chksum *lookup_checksum(Id solvid, Id keyname) {
1411     Id type = 0;
1412     const unsigned char *b = repodata_lookup_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, &type);
1413     return sat_chksum_create_from_bin(type, b);
1414   }
1415   void internalize() {
1416     repodata_internalize($self->repo->repodata + $self->id);
1417   }
1418   void create_stubs() {
1419     repodata_create_stubs($self->repo->repodata + $self->id);
1420   }
1421   void write(FILE *fp) {
1422     repodata_write($self->repo->repodata + $self->id, fp, repo_write_stdkeyfilter, 0);
1423   }
1424   bool read_solv_flags(FILE *fp, int flags = 0) {
1425     Repodata *data = $self->repo->repodata + $self->id;
1426     int r, oldstate = data->state;
1427     data->state = REPODATA_LOADING;
1428     r = repo_add_solv_flags(data->repo, fp, flags | REPO_USE_LOADING);
1429     if (r)
1430       data->state = oldstate;
1431     return r;
1432   }
1433   void extend_to_repo() {
1434     Repodata *data = $self->repo->repodata + $self->id;
1435     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
1436   }
1437 }