e395f2a33554308a2faa6a296a2b31e11145f0a8
[platform/upstream/libsolv.git] / examples / 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 #if defined(SWIGPYTHON)
19 %typemap(in) Queue {
20   /* Check if is a list */
21   queue_init(&$1);
22   if (PyList_Check($input)) {
23     int size = PyList_Size($input);
24     int i = 0;
25     for (i = 0; i < size; i++) {
26       PyObject *o = PyList_GetItem($input,i);
27       int v;
28       int e = SWIG_AsVal_int(o, &v);
29       if (!SWIG_IsOK(e)) {
30         SWIG_exception_fail(SWIG_ArgError(e), "list must contain only integers");
31         queue_free(&$1);
32         return NULL;
33       }
34       queue_push(&$1, v);
35     }
36   } else {
37     PyErr_SetString(PyExc_TypeError,"not a list");
38     return NULL;
39   }
40 }
41
42 %typemap(out) Queue {
43   int i;
44   PyObject *o = PyList_New($1.count);
45   for (i = 0; i < $1.count; i++)
46     PyList_SetItem(o, i, SWIG_From_int($1.elements[i]));
47   queue_free(&$1);
48   $result = o;
49 }
50
51 %define Queue2Array(type, step, con) %{
52   int i;
53   int cnt = $1.count / step;
54   Id *idp = $1.elements;
55   PyObject *o = PyList_New(cnt);
56   for (i = 0; i < cnt; i++, idp += step)
57     {
58       Id id = *idp;
59 #define result resultx
60       type result = con;
61       $typemap(out, type)
62       PyList_SetItem(o, i, $result);
63 #undef result
64     }
65   queue_free(&$1);
66   $result = o;
67 %}
68
69 %enddef
70
71 #endif
72
73
74 #if defined(SWIGPERL)
75 %typemap(in) Queue {
76   AV *av;
77   int i, size;
78   queue_init(&$1);
79   if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV)
80     SWIG_croak("Argument $argnum is not an array reference.");
81   av = (AV*)SvRV($input);
82   size = av_len(av);
83   for (i = 0; i <= size; i++) {
84     SV **sv = av_fetch(av, i, 0);
85     int v;
86     int e = SWIG_AsVal_int(*sv, &v);
87     if (!SWIG_IsOK(e)) {
88       SWIG_croak("list must contain only integers");
89     }
90     queue_push(&$1, v);
91   }
92 }
93 # AV *o = newAV();
94 # av_push(o, SvREFCNT_inc(SWIG_From_int($1.elements[i])));
95 # $result = newRV_noinc((SV*)o); argvi++;
96 #
97 %typemap(out) Queue {
98   int i;
99   if (argvi + $1.count + 1>= items) {
100     EXTEND(sp, items - (argvi + $1.count + 1) + 1);
101   }
102   for (i = 0; i < $1.count; i++)
103     ST(argvi++) = SvREFCNT_inc(SWIG_From_int($1.elements[i]));
104   queue_free(&$1);
105   $result = 0;
106 }
107 %define Queue2Array(type, step, con) %{
108   int i;
109   int cnt = $1.count / step;
110   Id *idp = $1.elements;
111   if (argvi + cnt + 1 >= items) {
112     EXTEND(sp, items - (argvi + cnt + 1) + 1);
113   }
114   for (i = 0; i < cnt; i++, idp += step)
115     {
116       Id id = *idp;
117 #define result resultx
118       type result = con;
119       $typemap(out, type)
120       SvREFCNT_inc(ST(argvi - 1));
121 #undef result
122     }
123   queue_free(&$1);
124   $result = 0;
125 %}
126 %enddef
127
128 #endif
129
130 %typemap(arginit) Queue {
131   queue_init(&$1);
132 }
133 %typemap(freearg) Queue {
134   queue_free(&$1);
135 }
136
137 #if defined(SWIGRUBY)
138 %typemap(in) Queue {
139   int size, i;
140   VALUE *o;
141   queue_init(&$1);
142   size = RARRAY($input)->len;
143   i = 0;
144   o = RARRAY($input)->ptr;
145   for (i = 0; i < size; i++, o++) {
146     int v;
147     int e = SWIG_AsVal_int(*o, &v);
148     if (!SWIG_IsOK(e))
149       SWIG_croak("list must contain only integers");
150     queue_push(&$1, v);
151   }
152 }
153 %typemap(out) Queue {
154   int i;
155   VALUE o = rb_ary_new2($1.count);
156   for (i = 0; i < $1.count; i++)
157     rb_ary_store(o, i, SWIG_From_int($1.elements[i]));
158   queue_free(&$1);
159   $result = o;
160 }
161 %typemap(arginit) Queue {
162   queue_init(&$1);
163 }
164 %typemap(freearg) Queue {
165   queue_free(&$1);
166 }
167 %define Queue2Array(type, step, con) %{
168   int i;
169   int cnt = $1.count / step;
170   Id *idp = $1.elements;
171   VALUE o = rb_ary_new2(cnt);
172   for (i = 0; i < cnt; i++, idp += step)
173     {
174       Id id = *idp;
175 #define result resultx
176       type result = con;
177       $typemap(out, type)
178       rb_ary_store(o, i, $result);
179 #undef result
180     }
181   queue_free(&$1);
182   $result = o;
183 %}
184 %enddef
185 #endif
186
187
188
189
190 #if defined(SWIGPERL)
191
192 # work around a swig bug
193 %{
194 #undef SWIG_CALLXS
195 #ifdef PERL_OBJECT 
196 #  define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv,pPerl) 
197 #else 
198 #  ifndef MULTIPLICITY 
199 #    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv) 
200 #  else 
201 #    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(PERL_GET_THX, cv) 
202 #  endif 
203 #endif 
204 %}
205
206
207 %define perliter(class)
208   %perlcode {
209     sub class##::FETCH {
210       my $i = ${##class##::ITERATORS}{$_[0]};
211       if ($i) {
212         $_[1] == $i->[0] - 1 ? $i->[1] : undef;
213       } else {
214         $_[0]->__getitem__($_[1]);
215       }
216     }
217     sub class##::FETCHSIZE {
218       my $i = ${##class##::ITERATORS}{$_[0]};
219       if ($i) {
220         ($i->[1] = $_[0]->__next__()) ? ++$i->[0]  : 0;
221       } else {
222         $_[0]->__len__();
223       }
224     }
225   }
226 %enddef
227
228 %{
229
230 #define SWIG_PERL_ITERATOR      0x80
231
232 SWIGRUNTIMEINLINE SV *
233 SWIG_Perl_NewArrayObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int flags) {
234   SV *result = sv_newmortal();
235   if (ptr && (flags & (SWIG_SHADOW | SWIG_POINTER_OWN))) {
236     SV *self;
237     SV *obj=newSV(0);
238     AV *array=newAV();
239     HV *stash;
240     sv_setref_pv(obj, (char *) SWIG_Perl_TypeProxyName(t), ptr);
241     stash=SvSTASH(SvRV(obj));
242     if (flags & SWIG_POINTER_OWN) {
243       HV *hv;
244       GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE);
245       if (!isGV(gv))
246         gv_init(gv, stash, "OWNER", 5, FALSE);
247       hv=GvHVn(gv);
248       hv_store_ent(hv, obj, newSViv(1), 0);
249     }
250     if (flags & SWIG_PERL_ITERATOR) {
251       HV *hv;
252       GV *gv=*(GV**)hv_fetch(stash, "ITERATORS", 9, TRUE);
253       AV *av=newAV();
254       if (!isGV(gv))
255         gv_init(gv, stash, "ITERATORS", 9, FALSE);
256       hv=GvHVn(gv);
257       hv_store_ent(hv, obj, newRV_inc((SV *)av), 0);
258     }
259     sv_magic((SV *)array, (SV *)obj, 'P', Nullch, 0);
260     SvREFCNT_dec(obj);
261     self=newRV_noinc((SV *)array);
262     sv_setsv(result, self);
263     SvREFCNT_dec((SV *)self);
264     sv_bless(result, stash);
265   } else {
266     sv_setref_pv(result, (char *) SWIG_Perl_TypeProxyName(t), ptr);
267   }
268   return result;
269 }
270
271 %}
272
273 %typemap(out) Perlarray {
274   ST(argvi) = SWIG_Perl_NewArrayObj(SWIG_PERL_OBJECT_CALL SWIG_as_voidptr(result), $1_descriptor, $owner | $shadow); argvi++;
275 }
276 %typemap(out) Perliterator {
277   ST(argvi) = SWIG_Perl_NewArrayObj(SWIG_PERL_OBJECT_CALL SWIG_as_voidptr(result), $1_descriptor, $owner | $shadow | SWIG_PERL_ITERATOR); argvi++;
278 }
279
280 %typemap(out) Pool_solvable_iterator * = Perlarray;
281 %typemap(out) Pool_solvable_iterator * solvables_iter = Perliterator;
282 %typemap(out) Pool_repo_iterator * = Perlarray;
283 %typemap(out) Pool_repo_iterator * repos_iter = Perliterator;
284 %typemap(out) Repo_solvable_iterator * = Perlarray;
285 %typemap(out) Repo_solvable_iterator * solvables_iter = Perliterator;
286 %typemap(out) Dataiterator * = Perliterator;
287
288 #endif
289
290
291
292 #if defined(SWIGPYTHON)
293 typedef PyObject *AppObjectPtr;
294 %typemap(out) AppObjectPtr {
295   $result = $1;
296   Py_INCREF($result);
297 }
298 #endif
299 #if defined(SWIGPERL)
300 typedef SV *AppObjectPtr;
301 %typemap(in) AppObjectPtr {
302   $1 = SvROK($input) ? SvRV($input) : 0;
303 }
304 %typemap(out) AppObjectPtr {
305   $result = $1 ? newRV_inc($1) : newSV(0);
306   argvi++;
307 }
308 #endif
309 #if defined(SWIGRUBY)
310 typedef VALUE AppObjectPtr;
311 %typemap(in) AppObjectPtr {
312   $1 = (void *)$input;
313 }
314 %typemap(out) AppObjectPtr {
315   $result = (VALUE)$1;
316 }
317 #endif
318
319
320 %include "cdata.i"
321 #ifndef SWIGPERL
322 %include "file.i"
323 #endif
324 %include "typemaps.i"
325
326 %{
327 #include "stdio.h"
328 #include "sys/stat.h"
329
330 #include "pool.h"
331 #include "solver.h"
332 #include "policy.h"
333 #include "solverdebug.h"
334 #include "repo_solv.h"
335 #include "chksum.h"
336
337 #include "repo_rpmdb.h"
338 #include "repo_rpmmd.h"
339 #include "repo_write.h"
340 #include "repo_products.h"
341 #include "repo_susetags.h"
342 #include "repo_updateinfoxml.h"
343 #include "repo_deltainfoxml.h"
344 #include "repo_repomdxml.h"
345 #include "repo_content.h"
346 #include "sat_xfopen.h"
347
348 #define true 1
349 #define false 1
350
351 #define SOLVER_SOLUTION_ERASE -100
352 #define SOLVER_SOLUTION_REPLACE -101
353 typedef struct chksum Chksum;
354 typedef int bool;
355 typedef void *AppObjectPtr;
356
357 typedef struct {
358   Pool *pool;
359   Id id;
360 } XId;
361
362 typedef struct {
363   Pool *pool;
364   Id id;
365 } XSolvable;
366
367 typedef struct {
368   Solver *solv;
369   Id id;
370 } XRule;
371
372 typedef struct {
373   Repo *repo;
374   Id id;
375 } XRepodata;
376
377 typedef struct {
378   Pool *pool;
379   Id id;
380 } Pool_solvable_iterator;
381
382 typedef struct {
383   Pool *pool;
384   Id id;
385 } Pool_repo_iterator;
386
387 typedef struct {
388   Repo *repo;
389   Id id;
390 } Repo_solvable_iterator;
391
392 typedef struct {
393   Pool *pool;
394   Id how;
395   Id what;
396 } Job;
397
398 typedef struct {
399   Solver *solv;
400   Id id;
401 } Problem;
402
403 typedef struct {
404   Solver *solv;
405   Id problemid;
406   Id id;
407 } Solution;
408
409 typedef struct {
410   Solver *solv;
411   Id problemid;
412   Id solutionid;
413   Id id;
414
415   Id type;
416   Id p;
417   Id rp;
418 } Solutionelement;
419
420 typedef struct {
421   Solver *solv;
422   Id rid;
423   Id type;
424   Id source;
425   Id target;
426   Id dep;
427 } Ruleinfo;
428
429 typedef Dataiterator Datamatch;
430
431 %}
432
433 #ifdef SWIGRUBY
434 %mixin Dataiterator "Enumerable";
435 %mixin Pool_solvable_iterator "Enumerable";
436 %mixin Pool_repo_iterator "Enumerable";
437 %mixin Repo_solvable_iterator "Enumerable";
438 #endif
439
440 typedef int Id;
441
442 %include "knownid.h"
443
444 # from repodata.h
445 %constant Id SOLVID_META;
446 %constant Id SOLVID_POS;
447
448 %constant int REL_EQ;
449 %constant int REL_GT;
450 %constant int REL_LT;
451 %constant int REL_ARCH;
452
453 typedef struct {
454   Pool* const pool;
455   Id const id;
456 } XId;
457
458 typedef struct {
459   Pool* const pool;
460   Id const id;
461 } XSolvable;
462
463 typedef struct {
464   Solver* const solv;
465   Id const type;
466   Id const dep;
467 } Ruleinfo;
468
469 typedef struct {
470   Solver* const solv;
471   Id const id;
472 } XRule;
473
474 typedef struct {
475   Repo* const repo;
476   Id const id;
477 } XRepodata;
478
479 # put before pool/repo so we can access the constructor
480 %nodefaultdtor Dataiterator;
481 typedef struct {} Dataiterator;
482 typedef struct {} Pool_solvable_iterator;
483 typedef struct {} Pool_repo_iterator;
484 typedef struct {} Repo_solvable_iterator;
485
486 %nodefaultctor Datamatch;
487 %nodefaultdtor Datamatch;
488 typedef struct {
489   Pool * const pool;
490   Repo * const repo;
491   const Id solvid;
492 } Datamatch;
493
494 typedef struct {
495   Pool * const pool;
496   Id how;
497   Id what;
498 } Job;
499
500 %nodefaultctor Pool;
501 %nodefaultdtor Pool;
502 typedef struct {
503   AppObjectPtr appdata;
504 } Pool;
505
506 %nodefaultctor Repo;
507 %nodefaultdtor Repo;
508 typedef struct _Repo {
509   Pool * const pool;
510   const char * const name;
511   int priority;
512   int subpriority;
513   int const nsolvables;
514   AppObjectPtr appdata;
515 } Repo;
516
517 %nodefaultctor Solver;
518 %nodefaultdtor Solver;
519 typedef struct {
520   Pool * const pool;
521   bool fixsystem;
522   bool allowdowngrade;
523   bool allowarchchange;
524   bool allowvendorchange;
525   bool allowuninstall;
526   bool updatesystem;
527   bool noupdateprovide;
528   bool dosplitprovides;
529   bool dontinstallrecommended;
530   bool ignorealreadyrecommended;
531   bool dontshowinstalledrecommended;
532   bool distupgrade;
533   bool distupgrade_removeunsupported;
534   bool noinfarchcheck;
535 } Solver;
536
537 typedef struct chksum {
538 } Chksum;
539
540 %rename(xfopen) sat_xfopen;
541 %rename(xfopen_fd) sat_xfopen_fd;
542 %rename(xfopen_dup) sat_xfopen_dup;
543 %rename(xfclose) sat_xfclose;
544 %rename(xfileno) sat_xfileno;
545
546 FILE *sat_xfopen(const char *fn, const char *mode = 0);
547 FILE *sat_xfopen_fd(const char *fn, int fd, const char *mode = 0);
548 FILE *sat_xfopen_dup(const char *fn, int fd, const char *mode = 0);
549 int sat_xfclose(FILE *fp);
550 int sat_xfileno(FILE *fp);
551
552 %{
553   SWIGINTERN int sat_xfclose(FILE *fp) {
554     return fclose(fp);
555   }
556   SWIGINTERN int sat_xfileno(FILE *fp) {
557     return fileno(fp);
558   }
559   SWIGINTERN FILE *sat_xfopen_dup(const char *fn, int fd, const char *mode) {
560     fd = dup(fd);
561     return fd == -1 ? 0 : sat_xfopen_fd(fn, fd, mode);
562   }
563 %}
564
565 typedef struct {
566   Solver * const solv;
567   Id const id;
568 } Problem;
569
570 typedef struct {
571   Solver * const solv;
572   Id const problemid;
573   Id const id;
574 } Solution;
575
576 typedef struct {
577   Solver *const solv;
578   Id const problemid;
579   Id const solutionid;
580   Id const id;
581   Id const type;
582 } Solutionelement;
583
584 %nodefaultctor Transaction;
585 %nodefaultdtor Transaction;
586 typedef struct {
587   Pool * const pool;
588 } Transaction;
589
590
591
592 %extend Job {
593   static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
594   static const Id SOLVER_SOLVABLE_NAME = SOLVER_SOLVABLE_NAME;
595   static const Id SOLVER_SOLVABLE_PROVIDES = SOLVER_SOLVABLE_PROVIDES;
596   static const Id SOLVER_SOLVABLE_ONE_OF = SOLVER_SOLVABLE_ONE_OF;
597   static const Id SOLVER_SOLVABLE_REPO = SOLVER_SOLVABLE_REPO;
598   static const Id SOLVER_SOLVABLE_ALL = SOLVER_SOLVABLE_ALL;
599   static const Id SOLVER_SELECTMASK = SOLVER_SELECTMASK;
600   static const Id SOLVER_NOOP = SOLVER_NOOP;
601   static const Id SOLVER_INSTALL = SOLVER_INSTALL;
602   static const Id SOLVER_ERASE = SOLVER_ERASE;
603   static const Id SOLVER_UPDATE = SOLVER_UPDATE;
604   static const Id SOLVER_WEAKENDEPS = SOLVER_WEAKENDEPS;
605   static const Id SOLVER_NOOBSOLETES = SOLVER_NOOBSOLETES;
606   static const Id SOLVER_LOCK = SOLVER_LOCK;
607   static const Id SOLVER_DISTUPGRADE = SOLVER_DISTUPGRADE;
608   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
609   static const Id SOLVER_DROP_ORPHANED = SOLVER_DROP_ORPHANED;
610   static const Id SOLVER_USERINSTALLED = SOLVER_USERINSTALLED;
611   static const Id SOLVER_JOBMASK = SOLVER_JOBMASK;
612   static const Id SOLVER_WEAK = SOLVER_WEAK;
613   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
614   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
615   static const Id SOLVER_SETEV = SOLVER_SETEV;
616   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
617   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
618   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
619   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
620   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
621   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
622
623   Job(Pool *pool, Id how, Id what) {
624     Job *job = sat_calloc(1, sizeof(*job));
625     job->pool = pool;
626     job->how = how;
627     job->what = what;
628     return job;
629   }
630
631   const char *str() {
632     return pool_job2str($self->pool, $self->how, $self->what, 0);
633   }
634
635   Queue solvableids() {
636     Pool *pool = $self->pool;
637     Id p, pp, how;
638     Queue q;
639     queue_init(&q);
640     how = $self->how & SOLVER_SELECTMASK;
641     FOR_JOB_SELECT(p, pp, how, $self->what)
642       queue_push(&q, p);
643     return q;
644   }
645   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
646   %newobject solvables;
647   Queue solvables() {
648     return Job_solvableids($self);
649   }
650 }
651
652 %extend Chksum {
653   Chksum(Id type) {
654     return (Chksum *)sat_chksum_create(type);
655   }
656   Chksum(Id type, const char *hex) {
657     unsigned char buf[64];
658     int l = sat_chksum_len(type);
659     if (!l)
660       return 0;
661     if (sat_hex2bin(&hex, buf, sizeof(buf)) != l || hex[0])
662       return 0;
663     return (Chksum *)sat_chksum_create_from_bin(type, buf);
664   }
665   ~Chksum() {
666     sat_chksum_free($self, 0);
667   }
668   Id const type;
669   %{
670   SWIGINTERN Id Chksum_type_get(Chksum *chksum) {
671     return sat_chksum_get_type(chksum);
672   }
673   %}
674   void add(const char *str) {
675     sat_chksum_add($self, str, strlen((char *)str));
676   }
677   void add_fp(FILE *fp) {
678     char buf[4096];
679     int l;
680     while ((l = fread(buf, 1, sizeof(buf), fp)) > 0)
681       sat_chksum_add($self, buf, l);
682     rewind(fp);         /* convenience */
683   }
684   void add_fd(int fd) {
685     char buf[4096];
686     int l;
687     while ((l = read(fd, buf, sizeof(buf))) > 0)
688       sat_chksum_add($self, buf, l);
689     lseek(fd, 0, 0);    /* convenience */
690   }
691   void add_stat(const char *filename) {
692     struct stat stb;
693     if (stat(filename, &stb))
694       memset(&stb, 0, sizeof(stb));
695     sat_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev));
696     sat_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino));
697     sat_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
698     sat_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
699   }
700   bool matches(Chksum *othersum) {
701     int l;
702     const unsigned char *b, *bo;
703     if (!othersum)
704       return 0;
705     if (sat_chksum_get_type($self) != sat_chksum_get_type(othersum))
706       return 0;
707     b = sat_chksum_get($self, &l);
708     bo = sat_chksum_get(othersum, 0);
709     return memcmp(b, bo, l) == 0;
710   }
711   SWIGCDATA raw() {
712     int l;
713     const unsigned char *b;
714     b = sat_chksum_get($self, &l);
715     return cdata_void((void *)b, l);
716   }
717   %newobject hex;
718   char *hex() {
719     int l;
720     const unsigned char *b;
721     char *ret, *rp;
722
723     b = sat_chksum_get($self, &l);
724     ret = sat_malloc(2 * l + 1);
725     sat_bin2hex(b, l, ret);
726     return ret;
727   }
728 }
729
730
731
732 %extend Pool {
733   Pool() {
734     Pool *pool = pool_create();
735     return pool;
736   }
737   ~Pool() {
738   }
739   void set_debuglevel(int level) {
740     pool_setdebuglevel($self, level);
741   }
742 #if defined(SWIGPYTHON)
743   %{
744   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
745     XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
746     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
747     PyObject *result = PyEval_CallObject((PyObject *)d, args);
748     int ecode = 0;
749     int vresult = 0;
750     Py_DECREF(args);
751     if (!result)
752       return 0; /* exception */
753     ecode = SWIG_AsVal_int(result, &vresult);
754     Py_DECREF(result);
755     return SWIG_IsOK(ecode) ? vresult : 0;
756   }
757   %}
758   void set_loadcallback(PyObject *callable) {
759     if ($self->loadcallback == loadcallback)
760       Py_DECREF($self->loadcallbackdata);
761     if (callable)
762       Py_INCREF(callable);
763     pool_setloadcallback($self, callable ? loadcallback : 0, callable);
764   }
765 #endif
766 #if defined(SWIGPERL)
767   %{
768
769 SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
770   int count;
771   int ret = 0;
772   dSP;
773   XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
774
775   ENTER;
776   SAVETMPS;
777   PUSHMARK(SP);
778   XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_OWNER | SWIG_SHADOW));
779   PUTBACK;
780   count = perl_call_sv((SV *)d, G_EVAL|G_SCALAR);
781   SPAGAIN;
782   if (count)
783     ret = POPi;
784   PUTBACK;
785   FREETMPS;
786   LEAVE;
787   return ret;
788 }
789
790   %}
791   void set_loadcallback(SV *callable) {
792     if ($self->loadcallback == loadcallback)
793       SvREFCNT_dec($self->loadcallbackdata);
794     if (callable)
795       SvREFCNT_inc(callable);
796     pool_setloadcallback($self, callable ? loadcallback : 0, callable);
797   }
798 #endif
799
800   void free() {
801 #if defined(SWIGPYTHON) || defined(SWIGPERL)
802     Pool_set_loadcallback($self, 0);
803 #endif
804     pool_free($self);
805   }
806   Id str2id(const char *str, bool create=1) {
807     return str2id($self, str, create);
808   }
809   const char *id2str(Id id) {
810     return id2str($self, id);
811   }
812   const char *dep2str(Id id) {
813     return dep2str($self, id);
814   }
815   Id rel2id(Id name, Id evr, int flags, bool create=1) {
816     return rel2id($self, name, evr, flags, create);
817   }
818   Id id2langid(Id id, const char *lang, bool create=1) {
819     return pool_id2langid($self, id, lang, create);
820   }
821   void setarch(const char *arch) {
822     pool_setarch($self, arch);
823   }
824   Repo *add_repo(const char *name) {
825     return repo_create($self, name);
826   }
827   const char *lookup_str(Id entry, Id keyname) {
828     return pool_lookup_str($self, entry, keyname);
829   }
830   Id lookup_id(Id entry, Id keyname) {
831     return pool_lookup_id($self, entry, keyname);
832   }
833   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
834     return pool_lookup_num($self, entry, keyname, notfound);
835   }
836   bool lookup_void(Id entry, Id keyname) {
837     return pool_lookup_void($self, entry, keyname);
838   }
839   %newobject lookup_checksum;
840   Chksum *lookup_checksum(Id entry, Id keyname) {
841     Id type = 0;
842     const unsigned char *b = pool_lookup_bin_checksum($self, entry, keyname, &type);
843     return sat_chksum_create_from_bin(type, b);
844   }
845
846   %newobject Dataiterator;
847   Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
848     return new_Dataiterator($self, 0, p, key, match, flags);
849   }
850   const char *solvid2str(Id solvid) {
851     return solvid2str($self, solvid);
852   }
853   void addfileprovides() {
854     pool_addfileprovides($self);
855   }
856   Queue addfileprovides_ids() {
857     Queue r;
858     Id *addedfileprovides = 0;
859     queue_init(&r);
860     pool_addfileprovides_ids($self, $self->installed, &addedfileprovides);
861     if (addedfileprovides) {
862       for (; *addedfileprovides; addedfileprovides++)
863         queue_push(&r, *addedfileprovides);
864     }
865     return r;
866   }
867   void createwhatprovides() {
868     pool_createwhatprovides($self);
869   }
870
871   %newobject solvables;
872   Pool_solvable_iterator * const solvables;
873   %{
874   SWIGINTERN Pool_solvable_iterator * Pool_solvables_get(Pool *pool) {
875     return new_Pool_solvable_iterator(pool);
876   }
877   %}
878   %newobject solvables_iter;
879   Pool_solvable_iterator * solvables_iter() {
880     return new_Pool_solvable_iterator($self);
881   }
882
883   %newobject repos;
884   Pool_repo_iterator * const repos;
885   %{
886   SWIGINTERN Pool_repo_iterator * Pool_repos_get(Pool *pool) {
887     return new_Pool_repo_iterator(pool);
888   }
889   %}
890   %newobject repos_iter;
891   Pool_repo_iterator * repos_iter() {
892     return new_Pool_repo_iterator($self);
893   }
894
895   Repo *installed;
896   %{
897   SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
898     pool_set_installed(pool, installed);
899   }
900   Repo *Pool_installed_get(Pool *pool) {
901     return pool->installed;
902   }
903   %}
904
905   Queue providerids(Id dep) {
906     Pool *pool = $self;
907     Queue q;
908     Id p, pp;
909     queue_init(&q);
910     FOR_PROVIDES(p, pp, dep)
911       queue_push(&q, p);
912     return q;
913   }
914   Queue matchprovidingids(const char *match, int flags) {
915     Pool *pool = $self;
916     Queue q;
917     Id id;
918     queue_init(&q);
919     if (!flags) {
920       for (id = 1; id < pool->ss.nstrings; id++)
921         if (pool->whatprovides[id])
922           queue_push(&q, id);
923     } else {
924       Datamatcher ma;
925       if (!datamatcher_init(&ma, match, flags)) {
926         for (id = 1; id < pool->ss.nstrings; id++)
927           if (pool->whatprovides[id] && datamatcher_match(&ma, id2str(pool, id)))
928             queue_push(&q, id);
929         datamatcher_free(&ma);
930       }
931     }
932     return q;
933   }
934
935   Job *Job(Id how, Id what) {
936     return new_Job($self, how, what);
937   }
938
939   %typemap(out) Queue providers Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
940   %newobject providers;
941   Queue providers(Id dep) {
942     Pool *pool = $self;
943     Queue q;
944     Id p, pp;
945     queue_init(&q);
946     FOR_PROVIDES(p, pp, dep)
947       queue_push(&q, p);
948     return q;
949   }
950
951   Id towhatprovides(Queue q) {
952     return pool_queuetowhatprovides($self, &q);
953   }
954   bool isknownarch(Id id) {
955     Pool *pool = $self;
956     if (!id || id == ID_EMPTY)
957       return 0;
958     if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
959       return 1;
960     if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
961       return 0;
962     return 1;
963   }
964
965   %newobject Solver;
966   Solver *Solver() {
967     return solver_create($self);
968   }
969 }
970
971 %extend Repo {
972   static const int REPO_REUSE_REPODATA = REPO_REUSE_REPODATA;
973   static const int REPO_NO_INTERNALIZE = REPO_NO_INTERNALIZE;
974   static const int REPO_LOCALPOOL = REPO_LOCALPOOL;
975   static const int REPO_USE_LOADING = REPO_USE_LOADING;
976   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
977   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
978   static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES; /* repo_susetags */
979   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS ; /* repo_solv */
980
981   void free(bool reuseids = 0) {
982     repo_free($self, reuseids);
983   }
984   void empty(bool reuseids = 0) {
985     repo_empty($self, reuseids);
986   }
987 #ifdef SWIGRUBY
988   %rename("isempty?") isempty();
989 #endif
990   bool isempty() {
991     return !$self->nsolvables;
992   }
993   bool add_solv(const char *name, int flags = 0) {
994     FILE *fp = fopen(name, "r");
995     int r;
996     if (!fp)
997       return 0;
998     r = repo_add_solv_flags($self, fp, flags);
999     fclose(fp);
1000     return r == 0;
1001   }
1002   bool add_solv(FILE *fp, int flags = 0) {
1003     return repo_add_solv_flags($self, fp, flags) == 0;
1004   }
1005   bool add_products(const char *proddir, int flags = 0) {
1006     repo_add_products($self, proddir, 0, flags);
1007     return 1;
1008   }
1009   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
1010     repo_add_rpmmd($self, fp, language, flags);
1011     return 1;
1012   }
1013   bool add_rpmdb(Repo *ref, int flags = 0) {
1014     repo_add_rpmdb($self, ref, 0, flags);
1015     return 1;
1016   }
1017   Id add_rpm(const char *name, int flags = 0) {
1018     return repo_add_rpm($self, name, flags);
1019   }
1020   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
1021     repo_add_susetags($self, fp, defvendor, language, flags);
1022     return 1;
1023   }
1024   bool add_repomdxml(FILE *fp, int flags = 0) {
1025     repo_add_repomdxml($self, fp, flags);
1026     return 1;
1027   }
1028   bool add_content(FILE *fp, int flags = 0) {
1029     repo_add_content($self, fp, flags);
1030     return 1;
1031   }
1032   bool add_updateinfoxml(FILE *fp, int flags = 0) {
1033     repo_add_updateinfoxml($self, fp, flags);
1034     return 1;
1035   }
1036   bool add_deltainfoxml(FILE *fp, int flags = 0) {
1037     repo_add_deltainfoxml($self, fp, flags);
1038     return 1;
1039   }
1040   void internalize() {
1041     repo_internalize($self);
1042   }
1043   const char *lookup_str(Id entry, Id keyname) {
1044     return repo_lookup_str($self, entry, keyname);
1045   }
1046   Id lookup_id(Id entry, Id keyname) {
1047     return repo_lookup_id($self, entry, keyname);
1048   }
1049   unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
1050     return repo_lookup_num($self, entry, keyname, notfound);
1051   }
1052   void write(FILE *fp) {
1053     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
1054   }
1055   # HACK, remove if no longer needed!
1056   bool write_first_repodata(FILE *fp, int flags = 0) {
1057     int oldnrepodata = $self->nrepodata;
1058     $self->nrepodata = 1;
1059     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
1060     $self->nrepodata = oldnrepodata;
1061     return 1;
1062   }
1063
1064   %newobject Dataiterator;
1065   Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
1066     return new_Dataiterator($self->pool, $self, p, key, match, flags);
1067   }
1068
1069   Id const id;
1070   %{
1071   SWIGINTERN Id Repo_id_get(Repo *repo) {
1072     return repo->repoid;
1073   }
1074   %}
1075   Repo_solvable_iterator * const solvables;
1076   %{
1077   SWIGINTERN Repo_solvable_iterator * Repo_solvables_get(Repo *repo) {
1078     return new_Repo_solvable_iterator(repo);
1079   }
1080   %}
1081   %newobject solvables_iter;
1082   Repo_solvable_iterator *solvables_iter() {
1083     return new_Repo_solvable_iterator($self);
1084   }
1085
1086   XRepodata *add_repodata(int flags = 0) {
1087     Repodata *rd = repo_add_repodata($self, flags);
1088     return new_XRepodata($self, rd - $self->repodata);
1089   }
1090
1091   void create_stubs() {
1092     Repodata *data;
1093     if (!$self->nrepodata)
1094       return;
1095     data = $self->repodata  + ($self->nrepodata - 1);
1096     if (data->state != REPODATA_STUB)
1097       repodata_create_stubs(data);
1098   }
1099 #ifdef SWIGRUBY
1100   %rename("iscontiguous?") iscontiguous();
1101 #endif
1102   bool iscontiguous() {
1103     int i;
1104     for (i = $self->start; i < $self->end; i++)
1105       if ($self->pool->solvables[i].repo != $self)
1106         return 0;
1107     return 1;
1108   }
1109   XRepodata *first_repodata() {
1110      int i;
1111      if (!$self->nrepodata)
1112        return 0;
1113      /* make sure all repodatas but the first are extensions */
1114      if ($self->repodata[0].loadcallback)
1115         return 0;
1116      for (i = 1; i < $self->nrepodata; i++)
1117        if (!$self->repodata[i].loadcallback)
1118          return 0;       /* oops, not an extension */
1119      return new_XRepodata($self, 0);
1120    }
1121 }
1122
1123 %extend Dataiterator {
1124   static const int SEARCH_STRING = SEARCH_STRING;
1125   static const int SEARCH_SUBSTRING = SEARCH_SUBSTRING;
1126   static const int SEARCH_GLOB = SEARCH_GLOB;
1127   static const int SEARCH_REGEX = SEARCH_REGEX;
1128   static const int SEARCH_NOCASE = SEARCH_NOCASE;
1129   static const int SEARCH_FILES = SEARCH_FILES;
1130   static const int SEARCH_COMPLETE_FILELIST = SEARCH_COMPLETE_FILELIST;
1131
1132   Dataiterator(Pool *pool, Repo *repo, Id p, Id key, const char *match, int flags) {
1133     Dataiterator *di = sat_calloc(1, sizeof(*di));
1134     dataiterator_init(di, pool, repo, p, key, match, flags);
1135     return di;
1136   }
1137   ~Dataiterator() {
1138     dataiterator_free($self);
1139     sat_free($self);
1140   }
1141 #if defined(SWIGPYTHON)
1142   %newobject __iter__;
1143   Dataiterator *__iter__() {
1144     Dataiterator *ndi;
1145     ndi = sat_calloc(1, sizeof(*ndi));
1146     dataiterator_init_clone(ndi, $self);
1147     return ndi;
1148   }
1149   %rename("next") __next__();
1150   %exception __next__ {
1151     $action
1152     if (!result) {
1153       PyErr_SetString(PyExc_StopIteration,"no more matches");
1154       return NULL;
1155     }
1156   }
1157 #endif
1158
1159 #ifdef SWIGPERL
1160   perliter(solv::Dataiterator)
1161 #endif
1162
1163   %newobject __next__;
1164   Datamatch *__next__() {
1165     Dataiterator *ndi;
1166     if (!dataiterator_step($self)) {
1167       return 0;
1168     }
1169     ndi = sat_calloc(1, sizeof(*ndi));
1170     dataiterator_init_clone(ndi, $self);
1171     return ndi;
1172   }
1173 #ifdef SWIGRUBY
1174   void each() {
1175     Datamatch *d;
1176     while ((d = Dataiterator___next__($self)) != 0) {
1177       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(d), SWIGTYPE_p_Datamatch, SWIG_POINTER_OWN | 0));
1178     }
1179   }
1180 #endif
1181   void prepend_keyname(Id key) {
1182     dataiterator_prepend_keyname($self, key);
1183   }
1184   void skip_solvable() {
1185     dataiterator_skip_solvable($self);
1186   }
1187 }
1188
1189 %extend Datamatch {
1190   ~Datamatch() {
1191     dataiterator_free($self);
1192     sat_free($self);
1193   }
1194   %newobject solvable;
1195   XSolvable * const solvable;
1196   %{
1197   SWIGINTERN XSolvable *Datamatch_solvable_get(Dataiterator *di) {
1198     return new_XSolvable(di->pool, di->solvid);
1199   }
1200   %}
1201   Id key_id() {
1202     return $self->key->name;
1203   }
1204   const char *key_idstr() {
1205     return id2str($self->pool, $self->key->name);
1206   }
1207   Id keytype_id() {
1208     return $self->key->type;
1209   }
1210   const char *keytype_idstr() {
1211     return id2str($self->pool, $self->key->type);
1212   }
1213   Id match_id() {
1214      return $self->kv.id;
1215   }
1216   const char *match_idstr() {
1217      return id2str($self->pool, $self->kv.id);
1218   }
1219   const char *match_str() {
1220      return $self->kv.str;
1221   }
1222   int match_num() {
1223      return $self->kv.num;
1224   }
1225   int match_num2() {
1226      return $self->kv.num2;
1227   }
1228   void setpos_parent() {
1229     dataiterator_setpos_parent($self);
1230   }
1231 }
1232
1233 %extend Pool_solvable_iterator {
1234   Pool_solvable_iterator(Pool *pool) {
1235     Pool_solvable_iterator *s;
1236     s = sat_calloc(1, sizeof(*s));
1237     s->pool = pool;
1238     return s;
1239   }
1240 #if defined(SWIGPYTHON)
1241   %newobject __iter__;
1242   Pool_solvable_iterator *__iter__() {
1243     Pool_solvable_iterator *s;
1244     s = sat_calloc(1, sizeof(*s));
1245     *s = *$self;
1246     return s;
1247   }
1248   %rename("next") __next__();
1249   %exception __next__ {
1250     $action
1251     if (!result) {
1252       PyErr_SetString(PyExc_StopIteration,"no more matches");
1253       return NULL;
1254     }
1255   }
1256 #endif
1257
1258 #ifdef SWIGPERL
1259   perliter(solv::Pool_solvable_iterator)
1260 #endif
1261   %newobject __next__;
1262   XSolvable *__next__() {
1263     Pool *pool = $self->pool;
1264     XSolvable *s;
1265     if ($self->id >= pool->nsolvables)
1266       return 0;
1267     while (++$self->id < pool->nsolvables)
1268       if (pool->solvables[$self->id].repo)
1269         return new_XSolvable(pool, $self->id);
1270     return 0;
1271   }
1272 #ifdef SWIGRUBY
1273   void each() {
1274     XSolvable *n;
1275     while ((n = Pool_solvable_iterator___next__($self)) != 0) {
1276       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
1277     }
1278   }
1279 #endif
1280   %newobject __getitem__;
1281   XSolvable *__getitem__(Id key) {
1282     Pool *pool = $self->pool;
1283     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo)
1284       return new_XSolvable(pool, key);
1285     return 0;
1286   }
1287   int __len__() {
1288     return $self->pool->nsolvables;
1289   }
1290 }
1291
1292 %extend Pool_repo_iterator {
1293   Pool_repo_iterator(Pool *pool) {
1294     Pool_repo_iterator *s;
1295     s = sat_calloc(1, sizeof(*s));
1296     s->pool = pool;
1297     return s;
1298   }
1299 #if defined(SWIGPYTHON)
1300   %newobject __iter__;
1301   Pool_repo_iterator *__iter__() {
1302     Pool_repo_iterator *s;
1303     s = sat_calloc(1, sizeof(*s));
1304     *s = *$self;
1305     return s;
1306   }
1307   %rename("next") __next__();
1308   %exception __next__ {
1309     $action
1310     if (!result) {
1311       PyErr_SetString(PyExc_StopIteration,"no more matches");
1312       return NULL;
1313     }
1314   }
1315 #endif
1316   %newobject __next__;
1317   Repo *__next__() {
1318     Pool *pool = $self->pool;
1319     if ($self->id >= pool->nrepos + 1)
1320       return 0;
1321     while (++$self->id < pool->nrepos + 1) {
1322       Repo *r = pool_id2repo(pool, $self->id);
1323       if (r)
1324         return r;
1325     }
1326     return 0;
1327   }
1328 #ifdef SWIGRUBY
1329   void each() {
1330     Repo *n;
1331     while ((n = Pool_repo_iterator___next__($self)) != 0) {
1332       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p__Repo, SWIG_POINTER_OWN | 0));
1333     }
1334   }
1335 #endif
1336   Repo *__getitem__(Id key) {
1337     Pool *pool = $self->pool;
1338     if (key > 0 && key < pool->nrepos + 1)
1339       return pool_id2repo(pool, key);
1340     return 0;
1341   }
1342   int __len__() {
1343     return $self->pool->nrepos + 1;
1344   }
1345 }
1346
1347 %extend Repo_solvable_iterator {
1348   Repo_solvable_iterator(Repo *repo) {
1349     Repo_solvable_iterator *s;
1350     s = sat_calloc(1, sizeof(*s));
1351     s->repo = repo;
1352     return s;
1353   }
1354 #if defined(SWIGPYTHON)
1355   %newobject __iter__;
1356   Repo_solvable_iterator *__iter__() {
1357     Repo_solvable_iterator *s;
1358     s = sat_calloc(1, sizeof(*s));
1359     *s = *$self;
1360     return s;
1361   }
1362   %rename("next") __next__();
1363   %exception __next__ {
1364     $action
1365     if (!result) {
1366       PyErr_SetString(PyExc_StopIteration,"no more matches");
1367       return NULL;
1368     }
1369   }
1370 #endif
1371   %newobject __next__;
1372   XSolvable *__next__() {
1373     Repo *repo = $self->repo;
1374     Pool *pool = repo->pool;
1375     XSolvable *s;
1376     if (repo->start > 0 && $self->id < repo->start)
1377       $self->id = repo->start - 1;
1378     if ($self->id >= repo->end)
1379       return 0;
1380     while (++$self->id < repo->end)
1381       if (pool->solvables[$self->id].repo == repo)
1382         return new_XSolvable(pool, $self->id);
1383     return 0;
1384   }
1385 #ifdef SWIGRUBY
1386   void each() {
1387     XSolvable *n;
1388     while ((n = Repo_solvable_iterator___next__($self)) != 0) {
1389       rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_XSolvable, SWIG_POINTER_OWN | 0));
1390     }
1391   }
1392 #endif
1393   %newobject __getitem__;
1394   XSolvable *__getitem__(Id key) {
1395     Repo *repo = $self->repo;
1396     Pool *pool = repo->pool;
1397     if (key > 0 && key < pool->nsolvables && pool->solvables[key].repo == repo)
1398       return new_XSolvable(pool, key);
1399     return 0;
1400   }
1401   int __len__() {
1402     return $self->repo->pool->nsolvables;
1403   }
1404 }
1405
1406 %extend XId {
1407   XId(Pool *pool, Id id) {
1408     XId *s;
1409     if (!id)
1410       return 0;
1411     s = sat_calloc(1, sizeof(*s));
1412     s->pool = pool;
1413     s->id = id;
1414     return s;
1415   }
1416   const char *str() {
1417     return dep2str($self->pool, $self->id);
1418   }
1419 }
1420
1421 %extend XSolvable {
1422   XSolvable(Pool *pool, Id id) {
1423     XSolvable *s;
1424     if (!id)
1425       return 0;
1426     s = sat_calloc(1, sizeof(*s));
1427     s->pool = pool;
1428     s->id = id;
1429     return s;
1430   }
1431   const char *str() {
1432     return solvid2str($self->pool, $self->id);
1433   }
1434   const char *lookup_str(Id keyname) {
1435     return pool_lookup_str($self->pool, $self->id, keyname);
1436   }
1437   Id lookup_id(Id keyname) {
1438     return pool_lookup_id($self->pool, $self->id, keyname);
1439   }
1440   unsigned int lookup_num(Id keyname, unsigned int notfound = 0) {
1441     return pool_lookup_num($self->pool, $self->id, keyname, notfound);
1442   }
1443   bool lookup_void(Id keyname) {
1444     return pool_lookup_void($self->pool, $self->id, keyname);
1445   }
1446   %newobject lookup_checksum;
1447   Chksum *lookup_checksum(Id keyname) {
1448     Id type = 0;
1449     const unsigned char *b = pool_lookup_bin_checksum($self->pool, $self->id, keyname, &type);
1450     return sat_chksum_create_from_bin(type, b);
1451   }
1452   const char *lookup_location(int *OUTPUT) {
1453     return solvable_get_location($self->pool->solvables + $self->id, OUTPUT);
1454   }
1455 #ifdef SWIGRUBY
1456   %rename("installable?") installable();
1457 #endif
1458   bool installable() {
1459     return pool_installable($self->pool, pool_id2solvable($self->pool, $self->id));
1460   }
1461   bool isinstalled() {
1462     Pool *pool = $self->pool;
1463     return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed;
1464   }
1465
1466   const char * const name;
1467   %{
1468     SWIGINTERN const char *XSolvable_name_get(XSolvable *xs) {
1469       Pool *pool = xs->pool;
1470       return id2str(pool, pool->solvables[xs->id].name);
1471     }
1472   %}
1473   Id const nameid;
1474   %{
1475     SWIGINTERN Id XSolvable_nameid_get(XSolvable *xs) {
1476       return xs->pool->solvables[xs->id].name;
1477     }
1478   %}
1479   const char * const evr;
1480   %{
1481     SWIGINTERN const char *XSolvable_evr_get(XSolvable *xs) {
1482       Pool *pool = xs->pool;
1483       return id2str(pool, pool->solvables[xs->id].evr);
1484     }
1485   %}
1486   Id const evrid;
1487   %{
1488     SWIGINTERN Id XSolvable_evrid_get(XSolvable *xs) {
1489       return xs->pool->solvables[xs->id].evr;
1490     }
1491   %}
1492   const char * const arch;
1493   %{
1494     SWIGINTERN const char *XSolvable_arch_get(XSolvable *xs) {
1495       Pool *pool = xs->pool;
1496       return id2str(pool, pool->solvables[xs->id].arch);
1497     }
1498   %}
1499   Id const archid;
1500   %{
1501     SWIGINTERN Id XSolvable_archid_get(XSolvable *xs) {
1502       return xs->pool->solvables[xs->id].arch;
1503     }
1504   %}
1505   const char * const vendor;
1506   %{
1507     SWIGINTERN const char *XSolvable_vendor_get(XSolvable *xs) {
1508       Pool *pool = xs->pool;
1509       return id2str(pool, pool->solvables[xs->id].vendor);
1510     }
1511   %}
1512   Id const vendorid;
1513   %{
1514     SWIGINTERN Id XSolvable_vendorid_get(XSolvable *xs) {
1515       return xs->pool->solvables[xs->id].vendor;
1516     }
1517   %}
1518   Repo * const repo;
1519   %{
1520     SWIGINTERN Repo *XSolvable_repo_get(XSolvable *xs) {
1521       return xs->pool->solvables[xs->id].repo;
1522     }
1523   %}
1524 }
1525
1526 %extend Problem {
1527   Problem(Solver *solv, Id id) {
1528     Problem *p;
1529     p = sat_calloc(1, sizeof(*p));
1530     p->solv = solv;
1531     p->id = id;
1532     return p;
1533   }
1534   %newobject findproblemrule;
1535   XRule *findproblemrule() {
1536     Id r = solver_findproblemrule($self->solv, $self->id);
1537     return new_XRule($self->solv, r);
1538   }
1539   %newobject findallproblemrules;
1540   %typemap(out) Queue findallproblemrules Queue2Array(XRule *, 1, new_XRule(arg1->solv, id));
1541   Queue findallproblemrules(int unfiltered=0) {
1542     Solver *solv = $self->solv;
1543     Id probr;
1544     int i, j;
1545     Queue q;
1546     queue_init(&q);
1547     solver_findallproblemrules(solv, $self->id, &q);
1548     if (!unfiltered)
1549       {
1550         for (i = j = 0; i < q.count; i++)
1551           {
1552             probr = q.elements[i];
1553             if ((probr >= solv->updaterules && probr < solv->updaterules_end) || (probr >= solv->jobrules && probr < solv->jobrules_end))
1554               continue;
1555             q.elements[j++] = probr;
1556           }
1557         if (j)
1558           queue_truncate(&q, j);
1559       }
1560     return q;
1561   }
1562   int solution_count() {
1563     return solver_solution_count($self->solv, $self->id);
1564   }
1565   %newobject solutions;
1566   %typemap(out) Queue solutions Queue2Array(Solution *, 1, new_Solution(arg1, id));
1567   Queue solutions() {
1568     Queue q;
1569     int i, cnt;
1570     queue_init(&q);
1571     cnt = solver_solution_count($self->solv, $self->id);
1572     for (i = 1; i <= cnt; i++)
1573       queue_push(&q, i);
1574     return q;
1575   }
1576 }
1577
1578 %extend Solution {
1579   Solution(Problem *p, Id id) {
1580     Solution *s;
1581     s = sat_calloc(1, sizeof(*s));
1582     s->solv = p->solv;
1583     s->problemid = p->id;
1584     s->id = id;
1585     return s;
1586   }
1587   int element_count() {
1588     return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
1589   }
1590   %newobject elements;
1591   %typemap(out) Queue elements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1, id));
1592   Queue elements() {
1593     Queue q;
1594     int i, cnt;
1595     queue_init(&q);
1596     cnt = solver_solution_count($self->solv, $self->id);
1597     for (i = 1; i <= cnt; i++)
1598       queue_push(&q, i);
1599     return q;
1600   }
1601 }
1602
1603 %extend Solutionelement {
1604   Solutionelement(Solution *s, Id id) {
1605     Solutionelement *e;
1606     e = sat_calloc(1, sizeof(*e));
1607     e->solv = s->solv;
1608     e->problemid = s->problemid;
1609     e->solutionid = s->id;
1610     e->id = id;
1611     solver_next_solutionelement(e->solv, e->problemid, e->solutionid, e->id - 1, &e->p, &e->rp);
1612     if (e->p > 0) {
1613       e->type = e->rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE;
1614     } else {
1615       e->type = e->p;
1616       e->p = e->rp;
1617       e->rp = 0;
1618     }
1619     return e;
1620   }
1621   int illegalreplace() {
1622     if ($self->type != SOLVER_SOLUTION_REPLACE || $self->p <= 0 || $self->rp <= 0)
1623       return 0;
1624     return policy_is_illegal($self->solv, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp, 0);
1625   }
1626   %newobject solvable;
1627   XSolvable * const solvable;
1628   %newobject replacement;
1629   XSolvable * const replacement;
1630   int const jobidx;
1631   %{
1632     SWIGINTERN XSolvable *Solutionelement_solvable_get(Solutionelement *e) {
1633       return new_XSolvable(e->solv->pool, e->p);
1634     }
1635     SWIGINTERN XSolvable *Solutionelement_replacement_get(Solutionelement *e) {
1636       return new_XSolvable(e->solv->pool, e->rp);
1637     }
1638     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
1639       return (e->p - 1) / 2;
1640     }
1641   %}
1642   %newobject Job;
1643   Job *Job() {
1644     if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE)
1645       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->p);
1646     if ($self->type == SOLVER_SOLUTION_REPLACE)
1647       return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->rp);
1648     if ($self->type == SOLVER_SOLUTION_ERASE)
1649       return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE, $self->p);
1650     return 0;
1651   }
1652 }
1653
1654 %extend Solver {
1655   static const int SOLVER_RULE_UNKNOWN = SOLVER_RULE_UNKNOWN;
1656   static const int SOLVER_RULE_RPM = SOLVER_RULE_RPM;
1657   static const int SOLVER_RULE_RPM_NOT_INSTALLABLE = SOLVER_RULE_RPM_NOT_INSTALLABLE;
1658   static const int SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP = SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP;
1659   static const int SOLVER_RULE_RPM_PACKAGE_REQUIRES = SOLVER_RULE_RPM_PACKAGE_REQUIRES;
1660   static const int SOLVER_RULE_RPM_SELF_CONFLICT = SOLVER_RULE_RPM_SELF_CONFLICT;
1661   static const int SOLVER_RULE_RPM_PACKAGE_CONFLICT = SOLVER_RULE_RPM_PACKAGE_CONFLICT;
1662   static const int SOLVER_RULE_RPM_SAME_NAME = SOLVER_RULE_RPM_SAME_NAME;
1663   static const int SOLVER_RULE_RPM_PACKAGE_OBSOLETES = SOLVER_RULE_RPM_PACKAGE_OBSOLETES;
1664   static const int SOLVER_RULE_RPM_IMPLICIT_OBSOLETES = SOLVER_RULE_RPM_IMPLICIT_OBSOLETES;
1665   static const int SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES = SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES;
1666   static const int SOLVER_RULE_UPDATE = SOLVER_RULE_UPDATE;
1667   static const int SOLVER_RULE_FEATURE = SOLVER_RULE_FEATURE;
1668   static const int SOLVER_RULE_JOB = SOLVER_RULE_JOB;
1669   static const int SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP = SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP;
1670   static const int SOLVER_RULE_DISTUPGRADE = SOLVER_RULE_DISTUPGRADE;
1671   static const int SOLVER_RULE_INFARCH = SOLVER_RULE_INFARCH;
1672   static const int SOLVER_RULE_CHOICE = SOLVER_RULE_CHOICE;
1673   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
1674
1675   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
1676   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
1677   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
1678   static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE;
1679   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
1680
1681   static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE;
1682   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
1683   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
1684
1685   ~Solver() {
1686     solver_free($self);
1687   }
1688 #if defined(SWIGPYTHON)
1689   %pythoncode {
1690     def solve(self, jobs):
1691       j = []
1692       for job in jobs: j += [job.how, job.what]
1693       return self.solve_helper(j)
1694   }
1695 #endif
1696 #if defined(SWIGPERL)
1697   %perlcode {
1698     sub solv::Solver::solve {
1699       my ($self, $jobs) = @_;
1700       my @j = map {($_->{'how'}, $_->{'what'})} @$jobs;
1701       return $self->solve_helper(\@j);
1702     }
1703   }
1704 #endif
1705 #if defined(SWIGRUBY)
1706 %init %{
1707 rb_eval_string(
1708     "class Solv::Solver\n"
1709     "  def solve(jobs)\n"
1710     "    jl = []\n"
1711     "    jobs.each do |j| ; jl << j.how << j.what ; end\n"
1712     "    solve_helper(jl)\n"
1713     "  end\n"
1714     "end\n"
1715   );
1716 %}
1717 #endif
1718   %typemap(out) Queue solve_helper Queue2Array(Problem *, 1, new_Problem(arg1, id));
1719   %newobject solve_helper;
1720   Queue solve_helper(Queue jobs) {
1721     Queue q;
1722     int i, cnt;
1723     queue_init(&q);
1724     solver_solve($self, &jobs);
1725     cnt = solver_problem_count($self);
1726     for (i = 1; i <= cnt; i++)
1727       queue_push(&q, i);
1728     return q;
1729   }
1730   %newobject transaction;
1731   Transaction *transaction() {
1732     Transaction *t;
1733     t = sat_calloc(1, sizeof(*t));
1734     transaction_init_clone(t, &$self->trans);
1735     return t;
1736   }
1737 }
1738
1739 %extend Transaction {
1740   static const int SOLVER_TRANSACTION_IGNORE = SOLVER_TRANSACTION_IGNORE;
1741   static const int SOLVER_TRANSACTION_ERASE = SOLVER_TRANSACTION_ERASE;
1742   static const int SOLVER_TRANSACTION_REINSTALLED = SOLVER_TRANSACTION_REINSTALLED;
1743   static const int SOLVER_TRANSACTION_DOWNGRADED = SOLVER_TRANSACTION_DOWNGRADED;
1744   static const int SOLVER_TRANSACTION_CHANGED = SOLVER_TRANSACTION_CHANGED;
1745   static const int SOLVER_TRANSACTION_UPGRADED = SOLVER_TRANSACTION_UPGRADED;
1746   static const int SOLVER_TRANSACTION_OBSOLETED = SOLVER_TRANSACTION_OBSOLETED;
1747   static const int SOLVER_TRANSACTION_INSTALL = SOLVER_TRANSACTION_INSTALL;
1748   static const int SOLVER_TRANSACTION_REINSTALL = SOLVER_TRANSACTION_REINSTALL;
1749   static const int SOLVER_TRANSACTION_DOWNGRADE = SOLVER_TRANSACTION_DOWNGRADE;
1750   static const int SOLVER_TRANSACTION_CHANGE = SOLVER_TRANSACTION_CHANGE;
1751   static const int SOLVER_TRANSACTION_UPGRADE = SOLVER_TRANSACTION_UPGRADE;
1752   static const int SOLVER_TRANSACTION_OBSOLETES = SOLVER_TRANSACTION_OBSOLETES;
1753   static const int SOLVER_TRANSACTION_MULTIINSTALL = SOLVER_TRANSACTION_MULTIINSTALL;
1754   static const int SOLVER_TRANSACTION_MULTIREINSTALL = SOLVER_TRANSACTION_MULTIREINSTALL;
1755   static const int SOLVER_TRANSACTION_MAXTYPE = SOLVER_TRANSACTION_MAXTYPE;
1756   static const int SOLVER_TRANSACTION_SHOW_ACTIVE = SOLVER_TRANSACTION_SHOW_ACTIVE;
1757   static const int SOLVER_TRANSACTION_SHOW_ALL = SOLVER_TRANSACTION_SHOW_ALL;
1758   static const int SOLVER_TRANSACTION_SHOW_OBSOLETES = SOLVER_TRANSACTION_SHOW_OBSOLETES;
1759   static const int SOLVER_TRANSACTION_SHOW_MULTIINSTALL = SOLVER_TRANSACTION_SHOW_MULTIINSTALL;
1760   static const int SOLVER_TRANSACTION_CHANGE_IS_REINSTALL = SOLVER_TRANSACTION_CHANGE_IS_REINSTALL;
1761   static const int SOLVER_TRANSACTION_MERGE_VENDORCHANGES = SOLVER_TRANSACTION_MERGE_VENDORCHANGES;
1762   static const int SOLVER_TRANSACTION_MERGE_ARCHCHANGES = SOLVER_TRANSACTION_MERGE_ARCHCHANGES;
1763   static const int SOLVER_TRANSACTION_RPM_ONLY = SOLVER_TRANSACTION_RPM_ONLY;
1764   static const int SOLVER_TRANSACTION_ARCHCHANGE = SOLVER_TRANSACTION_ARCHCHANGE;
1765   static const int SOLVER_TRANSACTION_VENDORCHANGE = SOLVER_TRANSACTION_VENDORCHANGE;
1766   static const int SOLVER_TRANSACTION_KEEP_ORDERDATA = SOLVER_TRANSACTION_KEEP_ORDERDATA;
1767   ~Transaction() {
1768     transaction_free($self);
1769     sat_free($self);
1770   }
1771 #ifdef SWIGRUBY
1772   %rename("isempty?") isempty();
1773 #endif
1774   bool isempty() {
1775     return $self->steps.count == 0;
1776   }
1777   Queue classify_helper(int mode) {
1778     Queue q;
1779     queue_init(&q);
1780     transaction_classify($self, mode, &q);
1781     return q;
1782   }
1783   Queue classify_pkgs_helper(int mode, Id cl, Id from, Id to) {
1784     Queue q;
1785     queue_init(&q);
1786     transaction_classify_pkgs($self, mode, cl, from, to, &q);
1787     return q;
1788   }
1789   %newobject othersolvable;
1790   XSolvable *othersolvable(XSolvable *s) {
1791     Id op = transaction_obs_pkg($self, s->id);
1792     return new_XSolvable($self->pool, op);
1793   }
1794 #if defined(SWIGPYTHON)
1795   %pythoncode {
1796     def classify(self, mode = 0):
1797       r = []
1798       cr = self.classify_helper(mode)
1799       for type, cnt, fromid, toid in zip(*([iter(cr)] * 4)):
1800         if type != self.SOLVER_TRANSACTION_IGNORE:
1801           r.append([ type, [ self.pool.solvables[j] for j in self.classify_pkgs_helper(mode, type, fromid, toid) ], fromid, toid ])
1802       return r
1803     }
1804 #endif
1805 #if defined(SWIGPERL)
1806   %perlcode {
1807     sub solv::Transaction::classify {
1808       my ($self, $mode) = @_;
1809       $mode ||= 0;
1810       my @r = $self->classify_helper($mode);
1811       my @res;
1812       while (@r) {
1813         my ($type, $cnt, $fromid, $toid) = splice(@r, 0, 4);
1814         next if $type == $solv::Transaction::SOLVER_TRANSACTION_IGNORE;
1815         push @res, [$type, [ map {$self->{'pool'}->{'solvables'}->[$_]} $self->classify_pkgs_helper($mode, $type, $fromid, $toid) ], $fromid, $toid];
1816       }
1817       return @res;
1818     }
1819   }
1820 #endif
1821
1822   %typemap(out) Queue newpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
1823   %newobject newpackages;
1824   Queue newpackages() {
1825     Queue q;
1826     int cut;
1827     queue_init(&q);
1828     cut = transaction_installedresult(self, &q);
1829     queue_truncate(&q, cut);
1830     return q;
1831   }
1832
1833   %typemap(out) Queue keptpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
1834   %newobject keptpackages;
1835   Queue keptpackages() {
1836     Queue q;
1837     int cut;
1838     queue_init(&q);
1839     cut = transaction_installedresult(self, &q);
1840     if (cut)
1841       queue_deleten(&q, 0, cut);
1842     return q;
1843   }
1844
1845   %typemap(out) Queue steps Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
1846   %newobject steps ;
1847   Queue steps() {
1848     Queue q;
1849     queue_init_clone(&q, &$self->steps);
1850     return q;
1851   }
1852
1853   int steptype(XSolvable *s, int mode) {
1854     return transaction_type($self, s->id, mode);
1855   }
1856   int calc_installsizechange() {
1857     return transaction_calc_installsizechange($self);
1858   }
1859   void order(int flags) {
1860     transaction_order($self, flags);
1861   }
1862 }
1863
1864 %extend XRule {
1865   XRule(Solver *solv, Id id) {
1866     if (!id)
1867       return 0;
1868     XRule *xr = sat_calloc(1, sizeof(*xr));
1869     xr->solv = solv;
1870     xr->id = id;
1871     return xr;
1872   }
1873   Ruleinfo *info() {
1874     Id type, source, target, dep;
1875     type =  solver_ruleinfo($self->solv, $self->id, &source, &target, &dep);
1876     return new_Ruleinfo($self, type, source, target, dep);
1877   }
1878   %typemap(out) Queue allinfos Queue2Array(Ruleinfo *, 4, new_Ruleinfo(arg1, id, idp[1], idp[2], idp[3]));
1879   %newobject allinfos;
1880   Queue allinfos() {
1881     Queue q;
1882     queue_init(&q);
1883     solver_allruleinfos($self->solv, $self->id, &q);
1884     return q;
1885   }
1886 }
1887
1888 %extend Ruleinfo {
1889   Ruleinfo(XRule *r, Id type, Id source, Id target, Id dep) {
1890     Ruleinfo *ri = sat_calloc(1, sizeof(*ri));
1891     ri->solv = r->solv;
1892     ri->rid = r->id;
1893     ri->type = type;
1894     ri->source = source;
1895     ri->target = target;
1896     ri->dep = dep;
1897     return ri;
1898   }
1899   XSolvable * const solvable;
1900   XSolvable * const othersolvable;
1901   %{
1902     SWIGINTERN XSolvable *Ruleinfo_solvable_get(Ruleinfo *ri) {
1903       return new_XSolvable(ri->solv->pool, ri->source);
1904     }
1905     SWIGINTERN XSolvable *Ruleinfo_othersolvable_get(Ruleinfo *ri) {
1906       return new_XSolvable(ri->solv->pool, ri->target);
1907     }
1908   %}
1909   const char *problemstr() {
1910     return solver_problemruleinfo2str($self->solv, $self->type, $self->source, $self->target, $self->dep);
1911   }
1912 }
1913
1914 %extend XRepodata {
1915   XRepodata(Repo *repo, Id id) {
1916     XRepodata *xr = sat_calloc(1, sizeof(*xr));
1917     xr->repo = repo;
1918     xr->id = id;
1919     return xr;
1920   }
1921   Id new_handle() {
1922     return repodata_new_handle($self->repo->repodata + $self->id);
1923   }
1924   void set_id(Id solvid, Id keyname, Id id) {
1925     repodata_set_id($self->repo->repodata + $self->id, solvid, keyname, id);
1926   }
1927   void set_str(Id solvid, Id keyname, const char *str) {
1928     repodata_set_str($self->repo->repodata + $self->id, solvid, keyname, str);
1929   }
1930   void set_poolstr(Id solvid, Id keyname, const char *str) {
1931     repodata_set_poolstr($self->repo->repodata + $self->id, solvid, keyname, str);
1932   }
1933   void add_idarray(Id solvid, Id keyname, Id id) {
1934     repodata_add_idarray($self->repo->repodata + $self->id, solvid, keyname, id);
1935   }
1936   void add_flexarray(Id solvid, Id keyname, Id handle) {
1937     repodata_add_flexarray($self->repo->repodata + $self->id, solvid, keyname, handle);
1938   }
1939   void set_checksum(Id solvid, Id keyname, Chksum *chksum) {
1940     const unsigned char *buf = sat_chksum_get(chksum, 0);
1941     if (buf)
1942       repodata_set_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, sat_chksum_get_type(chksum), buf);
1943   }
1944   const char *lookup_str(Id solvid, Id keyname) {
1945     return repodata_lookup_str($self->repo->repodata + $self->id, solvid, keyname);
1946   }
1947   Queue lookup_idarray(Id solvid, Id keyname) {
1948     Queue r;
1949     queue_init(&r);
1950     repodata_lookup_idarray($self->repo->repodata + $self->id, solvid, keyname, &r);
1951     return r;
1952   }
1953   %newobject lookup_checksum;
1954   Chksum *lookup_checksum(Id solvid, Id keyname) {
1955     Id type = 0;
1956     const unsigned char *b = repodata_lookup_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, &type);
1957     return sat_chksum_create_from_bin(type, b);
1958   }
1959   void internalize() {
1960     repodata_internalize($self->repo->repodata + $self->id);
1961   }
1962   void create_stubs() {
1963     repodata_create_stubs($self->repo->repodata + $self->id);
1964   }
1965   void write(FILE *fp) {
1966     repodata_write($self->repo->repodata + $self->id, fp, repo_write_stdkeyfilter, 0);
1967   }
1968   bool read_solv_flags(FILE *fp, int flags = 0) {
1969     Repodata *data = $self->repo->repodata + $self->id;
1970     int r, oldstate = data->state;
1971     data->state = REPODATA_LOADING;
1972     r = repo_add_solv_flags(data->repo, fp, flags | REPO_USE_LOADING);
1973     if (r)
1974       data->state = oldstate;
1975     return r;
1976   }
1977   void extend_to_repo() {
1978     Repodata *data = $self->repo->repodata + $self->id;
1979     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
1980   }
1981 }
1982