Set up gtkdoc for razor.
Despite its name, gtkdoc doesn't require gtk+ and is a nice way to
generate DocBook format API documentation.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <sys/types.h>
36 #include "razor-internal.h"
40 provider_satisfies_requirement(struct razor_property *provider,
41 const char *provider_strings,
46 const char *provided = &provider_strings[provider->version];
51 if (flags & RAZOR_PROPERTY_LESS)
57 cmp = razor_versioncmp(provided, required);
59 switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
60 case RAZOR_PROPERTY_LESS:
63 case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
66 /* fall through: FIXME, make sure this is correct */
68 case RAZOR_PROPERTY_EQUAL:
72 /* "foo == 1.1" is satisfied by "foo 1.1-2" */
73 len = strlen(required);
74 if (!strncmp(required, provided, len) && provided[len] == '-')
78 case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
81 case RAZOR_PROPERTY_GREATER:
85 /* shouldn't happen */
89 #define TRANS_PACKAGE_PRESENT 1
90 #define TRANS_PACKAGE_UPDATE 2
91 #define TRANS_PROPERTY_SATISFIED 0x80000000
93 struct transaction_set {
94 struct razor_set *set;
99 struct razor_transaction {
100 int package_count, errors;
101 struct transaction_set system, upstream;
106 transaction_set_init(struct transaction_set *ts, struct razor_set *set)
111 count = set->packages.size / sizeof (struct razor_package);
112 ts->packages = zalloc(count * sizeof *ts->packages);
113 count = set->properties.size / sizeof (struct razor_property);
114 ts->properties = zalloc(count * sizeof *ts->properties);
118 transaction_set_release(struct transaction_set *ts)
121 free(ts->properties);
125 transaction_set_install_package(struct transaction_set *ts,
126 struct razor_package *package)
128 struct razor_package *pkgs;
132 pkgs = ts->set->packages.data;
134 if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
137 ts->packages[i] = TRANS_PACKAGE_PRESENT;
139 prop = list_first(&package->properties, &ts->set->property_pool);
141 ts->properties[prop->data]++;
142 prop = list_next(prop);
147 transaction_set_remove_package(struct transaction_set *ts,
148 struct razor_package *package)
150 struct razor_package *pkgs;
154 pkgs = ts->set->packages.data;
156 if (ts->packages[i] == 0)
161 prop = list_first(&package->properties, &ts->set->property_pool);
163 ts->properties[prop->data]--;
164 prop = list_next(prop);
168 struct razor_transaction *
169 razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
171 struct razor_transaction *trans;
172 struct razor_package *p, *spkgs, *pend;
174 trans = zalloc(sizeof *trans);
175 transaction_set_init(&trans->system, system);
176 transaction_set_init(&trans->upstream, upstream);
178 spkgs = trans->system.set->packages.data;
179 pend = trans->system.set->packages.data +
180 trans->system.set->packages.size;
181 for (p = spkgs; p < pend; p++)
182 transaction_set_install_package(&trans->system, p);
188 razor_transaction_install_package(struct razor_transaction *trans,
189 struct razor_package *package)
191 transaction_set_install_package(&trans->upstream, package);
196 razor_transaction_remove_package(struct razor_transaction *trans,
197 struct razor_package *package)
199 transaction_set_remove_package(&trans->system, package);
204 razor_transaction_update_package(struct razor_transaction *trans,
205 struct razor_package *package)
207 struct razor_package *spkgs, *upkgs, *end;
209 spkgs = trans->system.set->packages.data;
210 upkgs = trans->upstream.set->packages.data;
211 end = trans->system.set->packages.data +
212 trans->system.set->packages.size;
213 if (spkgs <= package && package < end)
214 trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
216 trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
220 struct razor_property *p, *start, *end;
226 prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
228 pi->p = ts->set->properties.data;
229 pi->start = ts->set->properties.data;
230 pi->end = ts->set->properties.data + ts->set->properties.size;
231 pi->pool = ts->set->string_pool.data;
232 pi->present = ts->properties;
236 prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
238 while (pi->p < pi->end) {
239 if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
240 (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
250 static struct razor_property *
251 prop_iter_seek_to(struct prop_iter *pi,
252 uint32_t flags, const char *match)
256 while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
259 if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
263 while (pi->p < pi->end &&
264 pi->p->name == name &&
265 (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
268 if (pi->p == pi->end || pi->p->name != name)
274 /* Remove packages from set that provide any of the matching (same
275 * name and type) providers from ppi onwards that match the
276 * requirement that rpi points to. */
278 remove_matching_providers(struct razor_transaction *trans,
279 struct prop_iter *ppi,
283 struct razor_property *p;
284 struct razor_package *pkg, *pkgs;
285 struct razor_package_iterator pkg_iter;
286 struct razor_set *set;
287 const char *n, *v, *a;
290 if (ppi->present == trans->system.properties)
291 set = trans->system.set;
293 set = trans->upstream.set;
295 pkgs = (struct razor_package *) set->packages.data;
296 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
299 p->name == ppi->p->name &&
300 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
302 if (!ppi->present[p - ppi->start])
304 if (!provider_satisfies_requirement(p, ppi->pool,
308 razor_package_iterator_init_for_property(&pkg_iter, set, p);
309 while (razor_package_iterator_next(&pkg_iter,
311 fprintf(stderr, "removing %s-%s\n", n, v);
312 razor_transaction_remove_package(trans, pkg);
318 flag_matching_providers(struct razor_transaction *trans,
319 struct prop_iter *ppi,
320 struct razor_property *r,
321 struct prop_iter *rpi,
324 struct razor_property *p;
325 struct razor_package *pkg, *pkgs;
326 struct razor_package_iterator pkg_iter;
327 struct razor_set *set;
328 const char *name, *version, *arch;
329 uint32_t *flags, type;
331 if (ppi->present == trans->system.properties) {
332 set = trans->system.set;
333 flags = trans->system.packages;
335 set = trans->upstream.set;
336 flags = trans->upstream.packages;
339 pkgs = (struct razor_package *) set->packages.data;
340 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
343 p->name == ppi->p->name &&
344 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
346 if (!ppi->present[p - ppi->start])
348 if (!provider_satisfies_requirement(p, ppi->pool,
350 &rpi->pool[r->version]))
353 razor_package_iterator_init_for_property(&pkg_iter, set, p);
354 while (razor_package_iterator_next(&pkg_iter, &pkg,
355 &name, &version, &arch)) {
357 fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
361 rpi->pool + r->version);
362 flags[pkg - pkgs] |= flag;
367 static struct razor_package *
368 pick_matching_provider(struct razor_set *set,
369 struct prop_iter *ppi,
373 struct razor_property *p;
374 struct razor_package *pkgs;
378 /* This is where we decide which pkgs to pull in to satisfy a
379 * requirement. There may be several different providers
380 * (different versions) and each version of a provider may
381 * come from a number of packages. We pick the first package
382 * from the first provider that matches. */
384 pkgs = set->packages.data;
385 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
388 p->name == ppi->p->name &&
389 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
390 ppi->present[p - ppi->start] == 0;
392 if (!provider_satisfies_requirement(p, ppi->pool,
396 i = list_first(&p->packages, &set->package_pool);
398 return &pkgs[i->data];
405 remove_obsoleted_packages(struct razor_transaction *trans)
407 struct razor_property *up;
408 struct razor_package *spkgs;
409 struct prop_iter spi, upi;
411 spkgs = trans->system.set->packages.data;
412 prop_iter_init(&spi, &trans->system);
413 prop_iter_init(&upi, &trans->upstream);
415 while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
416 if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
417 &upi.pool[up->name]))
419 remove_matching_providers(trans, &spi, up->flags,
420 &upi.pool[up->version]);
425 any_provider_satisfies_requirement(struct prop_iter *ppi,
429 struct razor_property *p;
432 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
435 p->name == ppi->p->name &&
436 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
438 if (ppi->present[p - ppi->start] > 0 &&
439 provider_satisfies_requirement(p, ppi->pool,
448 clear_requires_flags(struct transaction_set *ts)
450 struct razor_property *p;
454 count = ts->set->properties.size / sizeof *p;
455 p = ts->set->properties.data;
456 pool = ts->set->string_pool.data;
457 for (i = 0; i < count; i++) {
458 ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
459 if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
460 ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
465 razor_property_relation_to_string(struct razor_property *p)
467 switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
468 case RAZOR_PROPERTY_LESS:
471 case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
474 case RAZOR_PROPERTY_EQUAL:
477 case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
480 case RAZOR_PROPERTY_GREATER:
489 razor_property_type_to_string(struct razor_property *p)
491 switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
492 case RAZOR_PROPERTY_REQUIRES:
494 case RAZOR_PROPERTY_PROVIDES:
496 case RAZOR_PROPERTY_CONFLICTS:
498 case RAZOR_PROPERTY_OBSOLETES:
506 mark_satisfied_requires(struct razor_transaction *trans,
507 struct transaction_set *rts,
508 struct transaction_set *pts)
510 struct prop_iter rpi, ppi;
511 struct razor_property *rp;
513 prop_iter_init(&rpi, rts);
514 prop_iter_init(&ppi, pts);
516 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
517 if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
518 &rpi.pool[rp->name]))
521 if (any_provider_satisfies_requirement(&ppi, rp->flags,
522 &rpi.pool[rp->version]))
523 rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
528 mark_all_satisfied_requires(struct razor_transaction *trans)
530 clear_requires_flags(&trans->system);
531 clear_requires_flags(&trans->upstream);
532 mark_satisfied_requires(trans, &trans->system, &trans->system);
533 mark_satisfied_requires(trans, &trans->system, &trans->upstream);
534 mark_satisfied_requires(trans, &trans->upstream, &trans->system);
535 mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
539 update_unsatisfied_packages(struct razor_transaction *trans)
541 struct razor_package *spkgs, *pkg;
542 struct razor_property *sp;
543 struct prop_iter spi;
544 struct razor_package_iterator pkg_iter;
545 const char *name, *version, *arch;
547 spkgs = trans->system.set->packages.data;
548 prop_iter_init(&spi, &trans->system);
550 while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
551 if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
554 razor_package_iterator_init_for_property(&pkg_iter,
557 while (razor_package_iterator_next(&pkg_iter, &pkg,
558 &name, &version, &arch)) {
559 fprintf(stderr, "updating %s because %s %s %s "
561 name, spi.pool + sp->name,
562 razor_property_relation_to_string(sp),
563 spi.pool + sp->version);
564 trans->system.packages[pkg - spkgs] |=
565 TRANS_PACKAGE_UPDATE;
571 razor_transaction_update_all(struct razor_transaction *trans)
573 struct razor_package *p;
576 count = trans->system.set->packages.size / sizeof *p;
577 for (i = 0; i < count; i++)
578 trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
582 update_conflicted_packages(struct razor_transaction *trans)
584 struct razor_package *pkg, *spkgs;
585 struct razor_property *up, *sp;
586 struct prop_iter spi, upi;
587 struct razor_package_iterator pkg_iter;
588 const char *name, *version, *arch;
590 spkgs = trans->system.set->packages.data;
591 prop_iter_init(&spi, &trans->system);
592 prop_iter_init(&upi, &trans->upstream);
594 while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
595 if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
596 &spi.pool[sp->name]))
599 if (!any_provider_satisfies_requirement(&upi, sp->flags,
600 &spi.pool[sp->version]))
603 razor_package_iterator_init_for_property(&pkg_iter,
606 while (razor_package_iterator_next(&pkg_iter, &pkg,
607 &name, &version, &arch)) {
608 fprintf(stderr, "updating %s %s because it conflicts with %s",
609 name, version, spi.pool + sp->name);
610 trans->system.packages[pkg - spkgs] |=
611 TRANS_PACKAGE_UPDATE;
615 prop_iter_init(&spi, &trans->system);
616 prop_iter_init(&upi, &trans->upstream);
618 while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
619 sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
620 &upi.pool[upi.p->name]);
623 flag_matching_providers(trans, &spi, up, &upi,
624 TRANS_PACKAGE_UPDATE);
629 pull_in_requirements(struct razor_transaction *trans,
630 struct prop_iter *rpi, struct prop_iter *ppi)
632 struct razor_property *rp, *pp;
633 struct razor_package *pkg, *upkgs;
635 upkgs = trans->upstream.set->packages.data;
636 while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
637 if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
640 pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
641 &rpi->pool[rp->name]);
644 pkg = pick_matching_provider(trans->upstream.set,
646 &rpi->pool[rp->version]);
650 rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
652 fprintf(stderr, "pulling in %s-%s.%s which provides %s %s %s "
653 "to satisfy %s %s %s\n",
654 ppi->pool + pkg->name,
655 ppi->pool + pkg->version,
656 ppi->pool + pkg->arch,
657 ppi->pool + pp->name,
658 razor_property_relation_to_string(pp),
659 ppi->pool + pp->version,
660 &rpi->pool[rp->name],
661 razor_property_relation_to_string(rp),
662 &rpi->pool[rp->version]);
664 trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
669 pull_in_all_requirements(struct razor_transaction *trans)
671 struct prop_iter rpi, ppi;
673 prop_iter_init(&rpi, &trans->system);
674 prop_iter_init(&ppi, &trans->upstream);
675 pull_in_requirements(trans, &rpi, &ppi);
677 prop_iter_init(&rpi, &trans->upstream);
678 prop_iter_init(&ppi, &trans->upstream);
679 pull_in_requirements(trans, &rpi, &ppi);
683 flush_scheduled_system_updates(struct razor_transaction *trans)
685 struct razor_package_iterator *pi;
686 struct razor_package *p, *pkg, *spkgs;
687 struct prop_iter ppi;
688 const char *name, *version, *arch;
690 spkgs = trans->system.set->packages.data;
691 pi = razor_package_iterator_create(trans->system.set);
692 prop_iter_init(&ppi, &trans->upstream);
694 while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
695 if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
698 if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
701 pkg = pick_matching_provider(trans->upstream.set, &ppi,
702 RAZOR_PROPERTY_GREATER, version);
706 fprintf(stderr, "updating %s-%s to %s-%s\n",
708 &ppi.pool[pkg->name], &ppi.pool[pkg->version]);
710 razor_transaction_remove_package(trans, p);
711 razor_transaction_install_package(trans, pkg);
714 razor_package_iterator_destroy(pi);
718 flush_scheduled_upstream_updates(struct razor_transaction *trans)
720 struct razor_package_iterator *pi;
721 struct razor_package *p, *upkgs;
722 struct prop_iter spi;
723 const char *name, *version, *arch;
725 upkgs = trans->upstream.set->packages.data;
726 pi = razor_package_iterator_create(trans->upstream.set);
727 prop_iter_init(&spi, &trans->system);
729 while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
730 if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
733 if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
734 remove_matching_providers(trans,
738 razor_transaction_install_package(trans, p);
739 fprintf(stderr, "installing %s-%s\n", name, version);
744 razor_transaction_resolve(struct razor_transaction *trans)
748 flush_scheduled_system_updates(trans);
749 flush_scheduled_upstream_updates(trans);
751 while (last < trans->changes) {
752 last = trans->changes;
753 remove_obsoleted_packages(trans);
754 mark_all_satisfied_requires(trans);
755 update_unsatisfied_packages(trans);
756 update_conflicted_packages(trans);
757 pull_in_all_requirements(trans);
758 flush_scheduled_system_updates(trans);
759 flush_scheduled_upstream_updates(trans);
762 return trans->changes;
766 describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
768 struct razor_package_iterator pi;
769 struct razor_package *pkg;
770 const char *name, *version, *arch, *pool;
772 pool = set->string_pool.data;
773 if (pool[rp->version] == '\0') {
774 razor_package_iterator_init_for_property(&pi, set, rp);
775 while (razor_package_iterator_next(&pi, &pkg,
776 &name, &version, &arch))
777 fprintf(stderr, "%s is needed by %s-%s.%s\n",
779 name, version, arch);
781 razor_package_iterator_init_for_property(&pi, set, rp);
782 while (razor_package_iterator_next(&pi, &pkg,
783 &name, &version, &arch))
784 fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
786 razor_property_relation_to_string(rp),
788 name, version, arch);
793 razor_transaction_describe(struct razor_transaction *trans)
795 struct prop_iter rpi;
796 struct razor_property *rp;
799 flush_scheduled_system_updates(trans);
800 flush_scheduled_upstream_updates(trans);
801 mark_all_satisfied_requires(trans);
804 prop_iter_init(&rpi, &trans->system);
805 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
806 if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
807 describe_unsatisfied(trans->system.set, rp);
812 prop_iter_init(&rpi, &trans->upstream);
813 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
814 if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
815 describe_unsatisfied(trans->upstream.set, rp);
824 razor_transaction_unsatisfied_property(struct razor_transaction *trans,
830 struct razor_property *p;
832 prop_iter_init(&pi, &trans->system);
833 while (prop_iter_next(&pi, flags, &p)) {
834 if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
836 strcmp(&pi.pool[p->name], name) == 0 &&
837 strcmp(&pi.pool[p->version], version) == 0)
842 prop_iter_init(&pi, &trans->upstream);
843 while (prop_iter_next(&pi, flags, &p)) {
844 if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
846 strcmp(&pi.pool[p->name], name) == 0 &&
847 strcmp(&pi.pool[p->version], version) == 0)
856 razor_transaction_finish(struct razor_transaction *trans)
858 struct razor_merger *merger;
859 struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
863 s = trans->system.set->packages.data;
864 spkgs = trans->system.set->packages.data;
865 send = trans->system.set->packages.data +
866 trans->system.set->packages.size;
867 spool = trans->system.set->string_pool.data;
869 u = trans->upstream.set->packages.data;
870 upkgs = trans->upstream.set->packages.data;
871 uend = trans->upstream.set->packages.data +
872 trans->upstream.set->packages.size;
873 upool = trans->upstream.set->string_pool.data;
875 merger = razor_merger_create(trans->system.set, trans->upstream.set);
876 while (s < send || u < uend) {
877 if (s < send && u < uend)
878 cmp = strcmp(&spool[s->name], &upool[u->name]);
885 if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
886 razor_merger_add_package(merger, s);
888 } else if (cmp == 0) {
889 if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
890 razor_merger_add_package(merger, s);
891 if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
892 razor_merger_add_package(merger, u);
897 if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
898 razor_merger_add_package(merger, u);
903 razor_transaction_destroy(trans);
905 return razor_merger_finish(merger);
909 razor_transaction_destroy(struct razor_transaction *trans)
911 transaction_set_release(&trans->system);
912 transaction_set_release(&trans->upstream);