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 #define DEBUG_PARSE 0
static inline pkg_dependency_t * 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; 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->compare = compare;
dep->prev = head; pkg_node_insert_tail(&dep->iter, dep, list);
if (dep->prev != NULL)
dep->prev->next = dep;
#if DEBUG_PARSE #if DEBUG_PARSE
fprintf(error_msgout, "--> %s %d %s\n", dep->package, dep->compare, dep->version); 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; return dep;
} }
pkg_dependency_t * void
pkg_dependency_append(pkg_dependency_t *head, pkg_dependency_t *tail) pkg_dependency_append(pkg_list_t *list, pkg_dependency_t *tail)
{ {
pkg_dependency_t *node; pkg_node_insert_tail(&tail->iter, tail, list);
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;
} }
void 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) pkg_dependency_t *dep = node->data;
free(node->package);
if (node->version != NULL) if (dep->package != NULL)
free(node->version); free(dep->package);
free(node); if (dep->version != NULL)
free(dep->version);
free(dep);
} }
} }
pkg_dependency_t * void
pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends) pkg_dependency_parse_str(pkg_list_t *deplist_head, const char *depends)
{ {
parse_state_t state = OUTSIDE_MODULE; parse_state_t state = OUTSIDE_MODULE;
pkg_dependency_t *deplist = NULL;
pkg_comparator_t compare = PKG_ANY; pkg_comparator_t compare = PKG_ANY;
char cmpname[PKG_BUFSIZE]; char cmpname[PKG_BUFSIZE];
char buf[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) if (state == OUTSIDE_MODULE)
{ {
deplist = pkg_dependency_add(deplist, package, package_sz, NULL, 0, compare); pkg_dependency_add(deplist_head, package, package_sz, NULL, 0, compare);
if (deplist_head == NULL)
deplist_head = deplist;
compare = PKG_ANY; compare = PKG_ANY;
package_sz = 0; package_sz = 0;
@ -224,10 +205,7 @@ pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends)
#if DEBUG_PARSE #if DEBUG_PARSE
fprintf(error_msgout, "Found version: %s\n", version); fprintf(error_msgout, "Found version: %s\n", version);
#endif #endif
deplist = pkg_dependency_add(deplist, package, package_sz, version, version_sz, compare); pkg_dependency_add(deplist_head, package, package_sz, version, version_sz, compare);
if (deplist_head == NULL)
deplist_head = deplist;
compare = PKG_ANY; compare = PKG_ANY;
package_sz = 0; package_sz = 0;
@ -241,18 +219,13 @@ pkg_dependency_parse_str(pkg_dependency_t *deplist_head, const char *depends)
ptr++; ptr++;
} }
return deplist_head;
} }
pkg_dependency_t * void
pkg_dependency_parse(pkg_t *pkg, const char *depends) 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); char *kvdepends = pkg_tuple_parse(&pkg->vars, depends);
list = pkg_dependency_parse_str(list, kvdepends); pkg_dependency_parse_str(deplist, kvdepends);
free(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 static void
print_requires(pkg_t *pkg) 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", dep->package);
printf(" %s %s", pkg_get_comparator(node), node->version);
if (dep->version != NULL)
printf(" %s %s", pkg_get_comparator(dep), dep->version);
printf("\n"); printf("\n");
} }
@ -177,14 +179,16 @@ print_requires(pkg_t *pkg)
static void static void
print_requires_private(pkg_t *pkg) 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", dep->package);
printf(" %s %s", pkg_get_comparator(node), node->version);
if (dep->version != NULL)
printf(" %s %s", pkg_get_comparator(dep), dep->version);
printf("\n"); printf("\n");
} }
@ -193,15 +197,17 @@ print_requires_private(pkg_t *pkg)
static void static void
print_digraph_node(pkg_t *pkg, void *unused, unsigned int flags) print_digraph_node(pkg_t *pkg, void *unused, unsigned int flags)
{ {
pkg_dependency_t *node; pkg_node_t *node;
(void) unused; (void) unused;
(void) flags; (void) flags;
printf("\"%s\" [fontname=Sans fontsize=8]\n", pkg->id); 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 static bool
apply_requires(pkg_t *world, void *unused, int maxdepth, unsigned int flags) apply_requires(pkg_t *world, void *unused, int maxdepth, unsigned int flags)
{ {
pkg_dependency_t *iter; pkg_node_t *iter;
(void) unused; (void) unused;
(void) maxdepth; (void) maxdepth;
PKG_FOREACH_LIST_ENTRY(world->requires, iter) PKG_FOREACH_LIST_ENTRY(world->requires.head, iter)
{ {
pkg_t *pkg; 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); print_requires(pkg);
pkg_free(pkg); pkg_free(pkg);
} }
return true; return true;
} }
static bool static bool
apply_requires_private(pkg_t *world, void *unused, int maxdepth, unsigned int flags) apply_requires_private(pkg_t *world, void *unused, int maxdepth, unsigned int flags)
{ {
pkg_dependency_t *iter; pkg_node_t *iter;
(void) unused; (void) unused;
(void) maxdepth; (void) maxdepth;
PKG_FOREACH_LIST_ENTRY(world->requires, iter) PKG_FOREACH_LIST_ENTRY(world->requires.head, iter)
{ {
pkg_t *pkg; 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); print_requires_private(pkg);
pkg_free(pkg); pkg_free(pkg);
@ -671,16 +680,19 @@ main(int argc, char *argv[])
if (required_module_version != NULL) if (required_module_version != NULL)
{ {
pkg_t *pkg; 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]) while (argv[pkg_optind])
{ {
pkghead = pkg_dependency_parse_str(pkghead, argv[pkg_optind]); pkg_dependency_parse_str(&deplist, argv[pkg_optind]);
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); pkg = pkg_find(pkgiter->package, global_traverse_flags);
if (pkg == NULL) if (pkg == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -695,16 +707,19 @@ main(int argc, char *argv[])
if (required_exact_module_version != NULL) if (required_exact_module_version != NULL)
{ {
pkg_t *pkg; 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]) while (argv[pkg_optind])
{ {
pkghead = pkg_dependency_parse_str(pkghead, argv[pkg_optind]); pkg_dependency_parse_str(&deplist, argv[pkg_optind]);
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); pkg = pkg_find(pkgiter->package, global_traverse_flags);
if (pkg == NULL) if (pkg == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -719,16 +734,19 @@ main(int argc, char *argv[])
if (required_max_module_version != NULL) if (required_max_module_version != NULL)
{ {
pkg_t *pkg; 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]) while (argv[pkg_optind])
{ {
pkghead = pkg_dependency_parse_str(pkghead, argv[pkg_optind]); pkg_dependency_parse_str(&deplist, argv[pkg_optind]);
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); pkg = pkg_find(pkgiter->package, global_traverse_flags);
if (pkg == NULL) if (pkg == NULL)
return EXIT_FAILURE; 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")) else if (!strcasecmp(key, "LIBS.private"))
pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value); pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value);
else if (!strcasecmp(key, "Requires")) 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")) 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")) else if (!strcasecmp(key, "Conflicts"))
pkg->conflicts = pkg_dependency_parse(pkg, value); pkg_dependency_parse(pkg, &pkg->conflicts, value);
break; break;
case '=': case '=':
if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX) || strcasecmp(key, "prefix")) if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX) || strcasecmp(key, "prefix"))
@ -249,9 +249,9 @@ pkg_free(pkg_t *pkg)
pkg_cache_remove(pkg); pkg_cache_remove(pkg);
pkg_dependency_free(pkg->requires); pkg_dependency_free(&pkg->requires);
pkg_dependency_free(pkg->requires_private); pkg_dependency_free(&pkg->requires_private);
pkg_dependency_free(pkg->conflicts); pkg_dependency_free(&pkg->conflicts);
pkg_fragment_free(&pkg->cflags); pkg_fragment_free(&pkg->cflags);
pkg_fragment_free(&pkg->libs); 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 static inline unsigned int
pkg_walk_list(pkg_dependency_t *deplist, pkg_walk_list(pkg_list_t *deplist,
pkg_traverse_func_t func, pkg_traverse_func_t func,
void *data, void *data,
int depth, int depth,
unsigned int flags) unsigned int flags)
{ {
unsigned int eflags = PKG_ERRF_OK; 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; pkg_t *pkgdep;
if (*node->package == '\0') if (*depnode->package == '\0')
continue; continue;
pkgdep = pkg_verify_dependency(node, flags, &eflags); pkgdep = pkg_verify_dependency(depnode, flags, &eflags);
if (eflags != PKG_ERRF_OK) 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) if (pkgdep->flags & PKG_PROPF_SEEN)
{ {
pkg_unref(pkgdep); pkg_unref(pkgdep);
@ -876,29 +877,32 @@ pkg_walk_list(pkg_dependency_t *deplist,
} }
static inline unsigned int 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; 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; continue;
PKG_FOREACH_LIST_ENTRY(root->requires, depnode) PKG_FOREACH_LIST_ENTRY(root->requires.head, childnode)
{ {
pkg_t *pkgdep; 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; continue;
pkgdep = pkg_verify_dependency(node, flags, &eflags); pkgdep = pkg_verify_dependency(parentnode, flags, &eflags);
if (eflags == PKG_ERRF_OK) 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", 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), pkgdep->version, pkgdep->realname, root->realname, parentnode->package, pkg_get_comparator(parentnode),
node->version != NULL ? " " : "", node->version != NULL ? node->version : ""); 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, "It may be possible to ignore this conflict and continue, try the\n");
fprintf(error_msgout, "PKG_CONFIG_IGNORE_CONFLICTS environment variable.\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)) 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) if (eflags != PKG_ERRF_OK)
return eflags; 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) if (eflags != PKG_ERRF_OK)
return eflags; return eflags;
if (flags & PKGF_SEARCH_PRIVATE) 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) if (eflags != PKG_ERRF_OK)
return eflags; return eflags;
} }

16
pkg.h
View File

@ -59,7 +59,7 @@ struct pkg_fragment_ {
}; };
struct pkg_dependency_ { struct pkg_dependency_ {
struct pkg_dependency_ *prev, *next; pkg_node_t iter;
char *package; char *package;
pkg_comparator_t compare; pkg_comparator_t compare;
@ -95,9 +95,9 @@ struct pkg_ {
pkg_list_t libs_private; pkg_list_t libs_private;
pkg_list_t cflags; pkg_list_t cflags;
pkg_dependency_t *requires; pkg_list_t requires;
pkg_dependency_t *requires_private; pkg_list_t requires_private;
pkg_dependency_t *conflicts; pkg_list_t conflicts;
pkg_list_t vars; pkg_list_t vars;
@ -147,10 +147,10 @@ pkg_comparator_t pkg_comparator_lookup_by_name(const char *name);
/* parse.c */ /* parse.c */
pkg_t *pkg_new_from_file(const char *path, FILE *f, unsigned int flags); 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); void pkg_dependency_parse_str(pkg_list_t *deplist_head, const char *depends);
pkg_dependency_t *pkg_dependency_parse(pkg_t *pkg, const char *depends); void pkg_dependency_parse(pkg_t *pkg, pkg_list_t *deplist_head, const char *depends);
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);
void pkg_dependency_free(pkg_dependency_t *head); void pkg_dependency_free(pkg_list_t *list);
/* argvsplit.c */ /* argvsplit.c */
int pkg_argv_split(const char *src, int *argc, char ***argv); 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_FOREACH_LIST_ENTRY(list->head, iter)
{ {
pkg_queue_t *pkgq; pkg_queue_t *pkgq;
pkg_dependency_t *pkgdep;
pkgq = iter->data; pkgq = iter->data;
pkgdep = pkg_dependency_parse(world, pkgq->package); pkg_dependency_parse(world, &world->requires, pkgq->package);
if (pkgdep != NULL)
world->requires = pkg_dependency_append(world->requires, pkgdep);
else
return false;
} }
return true; return (world->requires.head != NULL);
} }
void void