- prereq.c (conflicts): detect conflicts
- prereq.c (prereq): pass list of conflicts of initial package
- test/conflict: regression test for basic conflict handling
- TODO: updated for partial implementation of conflicts
- Makefile (OBJS_qpkg): added fixup.o
- fixup.h, fixup.c (sort_versions): sort package versions
- qpkg.c (do_fixups, main): do fixups when done gobbling
- qpkg.h: need to include id.h to be self-contained
- test/sortver: test version sorting
- qpkg.c (list_all_packages): jrb indicates end-of-tree with pointer to
jrb_nil(), not NULL
- qpkg.c (list_all_packages, list_one_package): use ID2PF
- qpkg.c (list_all_packages): iterate over versions
- prereq.c: added section titles
- prereq.c (debug), qpkg.h, qpkg.c: made variable "debug" global and moved
it to qpkg.c
- qpkg.c (usage, main): new option -d to enable debugging
We define a cyclic dependency as the possibility (!) of the prerequisites
of a package X including a package that depends on X, and issue an error
if encountering such a situation.
Note that, if the dependencies of X can be resolved in a manner that does
not include the cyclic dependency, qpkg will still fail if it encounters
the cycle. Also note that qpkg (at least so far) does no perform an
exhaustive search to ferret out cyclic dependencies.
Furthermore, we don't consider that a cyclic dependency may not necessarily
imply a real life problem. E.g., if a package A contains elements X and
Y, with X needing package B, and the content of package B has a run-time
dependency on Y, the cyclic dependency between A and B would not exist
when considering its constituents. Since we don't have this information, we
just err on the side of caution.
- qpkg.h (enum flags): divide flags into categories (parse-time and
run-time) and add flag QPKG_ADDING to mark packets whose dependencies we
are processing
- prereq.c (resolve, prereq): track which packages we're tentatively
considering for installation and detect cyclic dependencies
- test/cyclic: regression test for detection of cyclic dependencies
- TODO: updated with recent changes
Until now, when considering adding a package, we processed its
dependencies after completing the current list of dependencies. E.g.,
if we had a package A that depended on B and C, B depended on D, and C
depended on E, then the sequence would have been A, B, C, ...
We now process the dependencies of a package immediately after
considering the package, so the sequence above would become A, B, D,
C, ...
The advantage of the new order is that it becomes easier to follow the
dependency tree, which will be beneficial for loop detection and for
ordering packages by installation order.
- prereq.c (resolve): change prerequisite resolution order such that the
dependencies of the package being considered are processed immediately,
instead of deferring them until the end of the current dependency list
- prereq.c (prereq): we can now pass the list of dependencies directly,
without needing a list of lists element
- test/resorder: test resolution order
- gobble.c (gobble_buf): list_with_version reversed the order of the list
items. It makes the behaviour of later algorithms more intuitive if we
maintain the file order.
The original idea was to just copy "stack" (now called "installed") to
"best" when done. In this case, "best" would remain NULL if "install"
had no entries, which would then be interpreted as a failure to resolve
the prerequisites.
However, since we allocate a new list for "best" anyway, this concern
no longer exists, and we can also get rid of the contorted mechanism
that was designed to work around this problem. (It was never put into
action because I wanted to make a regression test for it first.)
- prereq.c (prereq): removed commented-out and nonsensical avoidance of
false error
- test/prereq: added test case with no prerequisite
- Makefile (test, tests, valgrind): new targets to run regression tests
- test/Common: test harness (adapted from fped)
- test/minpkg: test minimum package definition
- test/prereq: test basic prerequisite queries
- gobble.c (compact_pkg, gobble_buf): renamed compact_pkg to finish_pkg
- gobble.c (finish_pkg): check that the package has a version
- gobble.c (finish_pkg): check that the package has an architecture
- gobble.c (finish_pkg): check that the package either has a file name or
is installed
- qpkg.h (struct pkg): added "arch" field for the architecture
- gobble.c (gobble_buf): record the architecture
- gobble.c (gobble_buf): fail if trying to set the file name twice
- qpkg.c (main): initialize trees before doing anything else, so that the
argument processing stays together
- id.h, id.c (make_id): return a "struct jrb *", so that we have access to
key and value
- gobble.c (ID, gobble_buf): adapt to above change
- gobble.c (compact_pkg, gobble_buf): keep the RB node reference instead
of awkwardly regenerating it via pkg->id->jrb
- id.h, id.c (first_id, next_id): removed
- qpkg.c (list_all_packages): use jrb_first/jrb_next instead of
first_id/next_id
- id.h, id.c (find_id): return the RB tree node instead of the ID
- qpkg.c (list_one_package, find_prereq): adapted for above change
- id.h: explain the role of key and value
- qpkg.h (enum flags, struct pkg): replaced "installed" with "flags", one
of them being QPKG_INSTALLED
- gobble.c (compact_pkg, gobble_buf), prereq.c (push, resolve): adapted
for above change
- TODO: added section for tasks done
- TODO: search tree optimization is done
- TODO: added idea of supporting other database formats in the same family
- Makefile: added automatic dependenceies (needs SHELL = /bin/bash)
- Makefile: added non-verbose builds
- Makefile (jlime): set CC_normal instead of CC, so that also cross-builds
can be non-verbose
- Makefile (openwrt): new target to cross-compile for OpenWRT with uClibc
- Makefile (spotless): added "spotless" target
- gobble.c: uClibc may not have posix_madvise, so replace it with a dummy
if building for uClibc
If the package database is sane, then we don't need to check that all
the field names match what we expect. This saves a few more CPU cycles.
However, if anything goes wrong, the consequences may be unpleasant.
Thus, we default to the slow but safe approach.
- jrb.h, jrb.c (jrb_find_or_insert): new function to look for a node and
to insert a new one if not found
- id.c (make_id): use jrb_find_or_insert to avoid looking up new nodes
twice
- TODO: report the improvement
- id.h (struct tree, comp_id, make_tree), id.c (comp_id, make_tree):
comparison function now takes "void *" (pointing to a "struct id")
arguments instead of "struct id *", for compatibility with jrb
- id.c (comp_id, do_comp_id): added wrapper to convert "void *" back to
"struct id *"
This is a change of the underlying mechanism but it's not polished or
optimized yet. The compare functions haven't been updated, so they work
but produce compiler warnings because of type mismatches.
- Makefile (OBJS): added jrb.o
- id.h, id.c: use jrb instead of own dumb binary trees
- TODO: brag about the efficiency improvement
- jrb.c (recolor, jrb_delete_node, jrb_nblack, jrb_free_tree): add space
to while(...
- jrb.c (jrb_delete_node): flatten deletion of internal node
- rbtest.c (main): add test of jrb_delete_node
This avoids turning a prerequisite search into a massacre of, guessed,
O(sqrt(2^requisites)).
- gobble.c (gobble_buf, compact_pkg): if a package being added has the same
version as an existing package with the same name, merge them and keep
only one
With the reduction of search depth, "prereq abiword" takes about 3 minutes
on my PC. (Obviously, this can still be improved.)
- gobble.c (gobble_buf): if pkg->id->value is NULL, just it as such
- prereq.c (push): abort if trying to consider a package already considered
or installed
- prereq.c (conflicts): before being satisfied with using an installed
package, make sure it really satisfies the requirement
- prereq.c (conflicts): abort if an installed package conflicts
- prereq.c (conflicts): added some debugging output (temporary)
- prereq.c (conflicts): cut the search if we can't do better than a
previous match