dependency: refactor to use pkg_list_t framework

pull/48/head
William Pitcock 2013-03-01 11:36:21 -06:00
parent 8330056dc1
commit 1fd95f90eb
5 changed files with 106 additions and 117 deletions

View File

@ -37,7 +37,7 @@ typedef enum {
#define DEBUG_PARSE 0
static inline pkg_dependency_t *
pkg_dependency_add(pkg_dependency_t *head, const char *package, size_t package_sz, const char *version, size_t version_sz, pkg_comparator_t compare)
pkg_dependency_add(pkg_list_t *list, const char *package, size_t package_sz, const char *version, size_t version_sz, pkg_comparator_t compare)
{
pkg_dependency_t *dep;
@ -49,9 +49,7 @@ pkg_dependency_add(pkg_dependency_t *head, const char *package, size_t package_s
dep->compare = compare;
dep->prev = head;
if (dep->prev != NULL)
dep->prev->next = dep;
pkg_node_insert_tail(&dep->iter, dep, list);
#if DEBUG_PARSE
fprintf(error_msgout, "--> %s %d %s\n", dep->package, dep->compare, dep->version);
@ -60,49 +58,35 @@ pkg_dependency_add(pkg_dependency_t *head, const char *package, size_t package_s
return dep;
}
pkg_dependency_t *
pkg_dependency_append(pkg_dependency_t *head, pkg_dependency_t *tail)
void
pkg_dependency_append(pkg_list_t *list, pkg_dependency_t *tail)
{
pkg_dependency_t *node;
if (head == NULL)
return tail;
/* skip to end of list */
PKG_FOREACH_LIST_ENTRY(head, node)
{
if (node->next == NULL)
break;
}
node->next = tail;
tail->prev = node;
return head;
pkg_node_insert_tail(&tail->iter, tail, list);
}
void
pkg_dependency_free(pkg_dependency_t *head)
pkg_dependency_free(pkg_list_t *list)
{
pkg_dependency_t *node, *next;
pkg_node_t *node, *next;
PKG_FOREACH_LIST_ENTRY_SAFE(head, next, node)
PKG_FOREACH_LIST_ENTRY_SAFE(list->head, next, node)
{
if (node->package != NULL)
free(node->package);
pkg_dependency_t *dep = node->data;
if (node->version != NULL)
free(node->version);
if (dep->package != NULL)
free(dep->package);
free(node);
if (dep->version != NULL)
free(dep->version);
free(dep);
}
}
pkg_dependency_t *
pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends)
void
pkg_dependency_parse_str(pkg_list_t *deplist_head, const char *depends)
{
parse_state_t state = OUTSIDE_MODULE;
pkg_dependency_t *deplist = NULL;
pkg_comparator_t compare = PKG_ANY;
char cmpname[PKG_BUFSIZE];
char buf[PKG_BUFSIZE];
@ -170,10 +154,7 @@ pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends)
if (state == OUTSIDE_MODULE)
{
deplist = pkg_dependency_add(deplist, package, package_sz, NULL, 0, compare);
if (deplist_head == NULL)
deplist_head = deplist;
pkg_dependency_add(deplist_head, package, package_sz, NULL, 0, compare);
compare = PKG_ANY;
package_sz = 0;
@ -224,10 +205,7 @@ pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends)
#if DEBUG_PARSE
fprintf(error_msgout, "Found version: %s\n", version);
#endif
deplist = pkg_dependency_add(deplist, package, package_sz, version, version_sz, compare);
if (deplist_head == NULL)
deplist_head = deplist;
pkg_dependency_add(deplist_head, package, package_sz, version, version_sz, compare);
compare = PKG_ANY;
package_sz = 0;
@ -241,18 +219,13 @@ pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends)
ptr++;
}
return deplist_head;
}
pkg_dependency_t *
pkg_dependency_parse(pkg_t *pkg, const char *depends)
void
pkg_dependency_parse(pkg_t *pkg, pkg_list_t *deplist, const char *depends)
{
pkg_dependency_t *list = NULL;
char *kvdepends = pkg_tuple_parse(&pkg->vars, depends);
list = pkg_dependency_parse_str(list, kvdepends);
pkg_dependency_parse_str(deplist, kvdepends);
free(kvdepends);
return list;
}

74
main.c
View File

@ -161,14 +161,16 @@ print_variables(pkg_t *pkg, void *unused, unsigned int flags)
static void
print_requires(pkg_t *pkg)
{
pkg_dependency_t *node;
pkg_node_t *node;
PKG_FOREACH_LIST_ENTRY(pkg->requires, node)
PKG_FOREACH_LIST_ENTRY(pkg->requires.head, node)
{
printf("%s", node->package);
pkg_dependency_t *dep = node->data;
if (node->version != NULL)
printf(" %s %s", pkg_get_comparator(node), node->version);
printf("%s", dep->package);
if (dep->version != NULL)
printf(" %s %s", pkg_get_comparator(dep), dep->version);
printf("\n");
}
@ -177,14 +179,16 @@ print_requires(pkg_t *pkg)
static void
print_requires_private(pkg_t *pkg)
{
pkg_dependency_t *node;
pkg_node_t *node;
PKG_FOREACH_LIST_ENTRY(pkg->requires_private, node)
PKG_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
{
printf("%s", node->package);
pkg_dependency_t *dep = node->data;
if (node->version != NULL)
printf(" %s %s", pkg_get_comparator(node), node->version);
printf("%s", dep->package);
if (dep->version != NULL)
printf(" %s %s", pkg_get_comparator(dep), dep->version);
printf("\n");
}
@ -193,15 +197,17 @@ print_requires_private(pkg_t *pkg)
static void
print_digraph_node(pkg_t *pkg, void *unused, unsigned int flags)
{
pkg_dependency_t *node;
pkg_node_t *node;
(void) unused;
(void) flags;
printf("\"%s\" [fontname=Sans fontsize=8]\n", pkg->id);
PKG_FOREACH_LIST_ENTRY(pkg->requires, node)
PKG_FOREACH_LIST_ENTRY(pkg->requires.head, node)
{
printf("\"%s\" -- \"%s\" [fontname=Sans fontsize=8]\n", node->package, pkg->id);
pkg_dependency_t *dep = node->data;
printf("\"%s\" -- \"%s\" [fontname=Sans fontsize=8]\n", dep->package, pkg->id);
}
}
@ -337,34 +343,37 @@ apply_libs(pkg_t *world, void *list_head, int maxdepth, unsigned int flags)
static bool
apply_requires(pkg_t *world, void *unused, int maxdepth, unsigned int flags)
{
pkg_dependency_t *iter;
pkg_node_t *iter;
(void) unused;
(void) maxdepth;
PKG_FOREACH_LIST_ENTRY(world->requires, iter)
PKG_FOREACH_LIST_ENTRY(world->requires.head, iter)
{
pkg_t *pkg;
pkg_dependency_t *dep = iter->data;
pkg = pkg_verify_dependency(iter, flags, NULL);
pkg = pkg_verify_dependency(dep, flags, NULL);
print_requires(pkg);
pkg_free(pkg);
}
return true;
}
static bool
apply_requires_private(pkg_t *world, void *unused, int maxdepth, unsigned int flags)
{
pkg_dependency_t *iter;
pkg_node_t *iter;
(void) unused;
(void) maxdepth;
PKG_FOREACH_LIST_ENTRY(world->requires, iter)
PKG_FOREACH_LIST_ENTRY(world->requires.head, iter)
{
pkg_t *pkg;
pkg_dependency_t *dep = iter->data;
pkg = pkg_verify_dependency(iter, flags | PKGF_SEARCH_PRIVATE, NULL);
pkg = pkg_verify_dependency(dep, flags | PKGF_SEARCH_PRIVATE, NULL);
print_requires_private(pkg);
pkg_free(pkg);
@ -671,16 +680,19 @@ main(int argc, char *argv[])
if (required_module_version != NULL)
{
pkg_t *pkg;
pkg_dependency_t *pkghead = NULL, *pkgiter = NULL;
pkg_node_t *node;
pkg_list_t deplist = PKG_LIST_INITIALIZER;
while (argv[pkg_optind])
{
pkghead = pkg_dependency_parse_str(pkghead, argv[pkg_optind]);
pkg_dependency_parse_str(&deplist, argv[pkg_optind]);
pkg_optind++;
}
PKG_FOREACH_LIST_ENTRY(pkghead, pkgiter)
PKG_FOREACH_LIST_ENTRY(deplist.head, node)
{
pkg_dependency_t *pkgiter = node->data;
pkg = pkg_find(pkgiter->package, global_traverse_flags);
if (pkg == NULL)
return EXIT_FAILURE;
@ -695,16 +707,19 @@ main(int argc, char *argv[])
if (required_exact_module_version != NULL)
{
pkg_t *pkg;
pkg_dependency_t *pkghead = NULL, *pkgiter = NULL;
pkg_node_t *node;
pkg_list_t deplist = PKG_LIST_INITIALIZER;
while (argv[pkg_optind])
{
pkghead = pkg_dependency_parse_str(pkghead, argv[pkg_optind]);
pkg_dependency_parse_str(&deplist, argv[pkg_optind]);
pkg_optind++;
}
PKG_FOREACH_LIST_ENTRY(pkghead, pkgiter)
PKG_FOREACH_LIST_ENTRY(deplist.head, node)
{
pkg_dependency_t *pkgiter = node->data;
pkg = pkg_find(pkgiter->package, global_traverse_flags);
if (pkg == NULL)
return EXIT_FAILURE;
@ -719,16 +734,19 @@ main(int argc, char *argv[])
if (required_max_module_version != NULL)
{
pkg_t *pkg;
pkg_dependency_t *pkghead = NULL, *pkgiter = NULL;
pkg_node_t *node;
pkg_list_t deplist = PKG_LIST_INITIALIZER;
while (argv[pkg_optind])
{
pkghead = pkg_dependency_parse_str(pkghead, argv[pkg_optind]);
pkg_dependency_parse_str(&deplist, argv[pkg_optind]);
pkg_optind++;
}
PKG_FOREACH_LIST_ENTRY(pkghead, pkgiter)
PKG_FOREACH_LIST_ENTRY(deplist.head, node)
{
pkg_dependency_t *pkgiter = node->data;
pkg = pkg_find(pkgiter->package, global_traverse_flags);
if (pkg == NULL)
return EXIT_FAILURE;

52
pkg.c
View File

@ -212,11 +212,11 @@ pkg_new_from_file(const char *filename, FILE *f, unsigned int flags)
else if (!strcasecmp(key, "LIBS.private"))
pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value);
else if (!strcasecmp(key, "Requires"))
pkg->requires = pkg_dependency_parse(pkg, value);
pkg_dependency_parse(pkg, &pkg->requires, value);
else if (!strcasecmp(key, "Requires.private"))
pkg->requires_private = pkg_dependency_parse(pkg, value);
pkg_dependency_parse(pkg, &pkg->requires_private, value);
else if (!strcasecmp(key, "Conflicts"))
pkg->conflicts = pkg_dependency_parse(pkg, value);
pkg_dependency_parse(pkg, &pkg->conflicts, value);
break;
case '=':
if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX) || strcasecmp(key, "prefix"))
@ -249,9 +249,9 @@ pkg_free(pkg_t *pkg)
pkg_cache_remove(pkg);
pkg_dependency_free(pkg->requires);
pkg_dependency_free(pkg->requires_private);
pkg_dependency_free(pkg->conflicts);
pkg_dependency_free(&pkg->requires);
pkg_dependency_free(&pkg->requires_private);
pkg_dependency_free(&pkg->conflicts);
pkg_fragment_free(&pkg->cflags);
pkg_fragment_free(&pkg->libs);
@ -837,25 +837,26 @@ pkg_report_graph_error(pkg_t *pkg, pkg_dependency_t *node, unsigned int eflags)
}
static inline unsigned int
pkg_walk_list(pkg_dependency_t *deplist,
pkg_walk_list(pkg_list_t *deplist,
pkg_traverse_func_t func,
void *data,
int depth,
unsigned int flags)
{
unsigned int eflags = PKG_ERRF_OK;
pkg_dependency_t *node;
pkg_node_t *node;
PKG_FOREACH_LIST_ENTRY(deplist, node)
PKG_FOREACH_LIST_ENTRY(deplist->head, node)
{
pkg_dependency_t *depnode = node->data;
pkg_t *pkgdep;
if (*node->package == '\0')
if (*depnode->package == '\0')
continue;
pkgdep = pkg_verify_dependency(node, flags, &eflags);
pkgdep = pkg_verify_dependency(depnode, flags, &eflags);
if (eflags != PKG_ERRF_OK)
return pkg_report_graph_error(pkgdep, node, eflags);
return pkg_report_graph_error(pkgdep, depnode, eflags);
if (pkgdep->flags & PKG_PROPF_SEEN)
{
pkg_unref(pkgdep);
@ -876,29 +877,32 @@ pkg_walk_list(pkg_dependency_t *deplist,
}
static inline unsigned int
pkg_walk_conflicts_list(pkg_t *root, pkg_dependency_t *deplist, unsigned int flags)
pkg_walk_conflicts_list(pkg_t *root, pkg_list_t *deplist, unsigned int flags)
{
unsigned int eflags;
pkg_dependency_t *node, *depnode;
pkg_node_t *node, *childnode;
PKG_FOREACH_LIST_ENTRY(deplist, node)
PKG_FOREACH_LIST_ENTRY(deplist->head, node)
{
if (*node->package == '\0')
pkg_dependency_t *parentnode = node->data;
if (*parentnode->package == '\0')
continue;
PKG_FOREACH_LIST_ENTRY(root->requires, depnode)
PKG_FOREACH_LIST_ENTRY(root->requires.head, childnode)
{
pkg_t *pkgdep;
pkg_dependency_t *depnode = childnode->data;
if (*depnode->package == '\0' || strcmp(depnode->package, node->package))
if (*depnode->package == '\0' || strcmp(depnode->package, parentnode->package))
continue;
pkgdep = pkg_verify_dependency(node, flags, &eflags);
pkgdep = pkg_verify_dependency(parentnode, flags, &eflags);
if (eflags == PKG_ERRF_OK)
{
fprintf(error_msgout, "Version '%s' of '%s' conflicts with '%s' due to satisfying conflict rule '%s %s%s%s'.\n",
pkgdep->version, pkgdep->realname, root->realname, node->package, pkg_get_comparator(node),
node->version != NULL ? " " : "", node->version != NULL ? node->version : "");
pkgdep->version, pkgdep->realname, root->realname, parentnode->package, pkg_get_comparator(parentnode),
parentnode->version != NULL ? " " : "", parentnode->version != NULL ? parentnode->version : "");
fprintf(error_msgout, "It may be possible to ignore this conflict and continue, try the\n");
fprintf(error_msgout, "PKG_CONFIG_IGNORE_CONFLICTS environment variable.\n");
@ -940,18 +944,18 @@ pkg_traverse(pkg_t *root,
if (!(flags & PKGF_SKIP_CONFLICTS))
{
eflags = pkg_walk_conflicts_list(root, root->conflicts, rflags);
eflags = pkg_walk_conflicts_list(root, &root->conflicts, rflags);
if (eflags != PKG_ERRF_OK)
return eflags;
}
eflags = pkg_walk_list(root->requires, func, data, maxdepth, rflags);
eflags = pkg_walk_list(&root->requires, func, data, maxdepth, rflags);
if (eflags != PKG_ERRF_OK)
return eflags;
if (flags & PKGF_SEARCH_PRIVATE)
{
eflags = pkg_walk_list(root->requires_private, func, data, maxdepth, rflags);
eflags = pkg_walk_list(&root->requires_private, func, data, maxdepth, rflags);
if (eflags != PKG_ERRF_OK)
return eflags;
}

16
pkg.h
View File

@ -59,7 +59,7 @@ struct pkg_fragment_ {
};
struct pkg_dependency_ {
struct pkg_dependency_ *prev, *next;
pkg_node_t iter;
char *package;
pkg_comparator_t compare;
@ -95,9 +95,9 @@ struct pkg_ {
pkg_list_t libs_private;
pkg_list_t cflags;
pkg_dependency_t *requires;
pkg_dependency_t *requires_private;
pkg_dependency_t *conflicts;
pkg_list_t requires;
pkg_list_t requires_private;
pkg_list_t conflicts;
pkg_list_t vars;
@ -147,10 +147,10 @@ pkg_comparator_t pkg_comparator_lookup_by_name(const char *name);
/* parse.c */
pkg_t *pkg_new_from_file(const char *path, FILE *f, unsigned int flags);
pkg_dependency_t *pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends);
pkg_dependency_t *pkg_dependency_parse(pkg_t *pkg, const char *depends);
pkg_dependency_t *pkg_dependency_append(pkg_dependency_t *head, pkg_dependency_t *tail);
void pkg_dependency_free(pkg_dependency_t *head);
void pkg_dependency_parse_str(pkg_list_t *deplist_head, const char *depends);
void pkg_dependency_parse(pkg_t *pkg, pkg_list_t *deplist_head, const char *depends);
void pkg_dependency_append(pkg_list_t *list, pkg_dependency_t *tail);
void pkg_dependency_free(pkg_list_t *list);
/* argvsplit.c */
int pkg_argv_split(const char *src, int *argc, char ***argv);

10
queue.c
View File

@ -38,18 +38,12 @@ pkg_queue_compile(pkg_t *world, pkg_list_t *list)
PKG_FOREACH_LIST_ENTRY(list->head, iter)
{
pkg_queue_t *pkgq;
pkg_dependency_t *pkgdep;
pkgq = iter->data;
pkgdep = pkg_dependency_parse(world, pkgq->package);
if (pkgdep != NULL)
world->requires = pkg_dependency_append(world->requires, pkgdep);
else
return false;
pkg_dependency_parse(world, &world->requires, pkgq->package);
}
return true;
return (world->requires.head != NULL);
}
void