コード例 #1
0
ファイル: alpm_list.c プロジェクト: 7799/pacman
/**
 * @brief Remove an item from the list.
 *
 * @param haystack the list to remove the item from
 * @param needle   the data member of the item we're removing
 * @param fn       the comparison function for searching
 * @param data     output parameter containing data of the removed item
 *
 * @return the resultant list
 */
alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
		const void *needle, alpm_list_fn_cmp fn, void **data)
{
	alpm_list_t *i = haystack;

	if(data) {
		*data = NULL;
	}

	if(needle == NULL) {
		return haystack;
	}

	while(i) {
		if(i->data == NULL) {
			i = i->next;
			continue;
		}
		if(fn(i->data, needle) == 0) {
			haystack = alpm_list_remove_item(haystack, i);

			if(data) {
				*data = i->data;
			}
			free(i);
			break;
		} else {
			i = i->next;
		}
	}

	return haystack;
}
コード例 #2
0
ファイル: deps.c プロジェクト: gtmanfred/pacman
/* Convert a list of alpm_pkg_t * to a graph structure,
 * with a edge for each dependency.
 * Returns a list of vertices (one vertex = one package)
 * (used by alpm_sortbydeps)
 */
static alpm_list_t *dep_graph_init(alpm_handle_t *handle,
		alpm_list_t *targets, alpm_list_t *ignore)
{
	alpm_list_t *i, *j;
	alpm_list_t *vertices = NULL;
	alpm_list_t *localpkgs = alpm_list_diff(
			alpm_db_get_pkgcache(handle->db_local), ignore, ptr_cmp);

	/* We create the vertices */
	for(i = targets; i; i = i->next) {
		alpm_graph_t *vertex = _alpm_graph_new();
		vertex->data = (void *)i->data;
		vertices = alpm_list_add(vertices, vertex);
	}

	/* We compute the edges */
	for(i = vertices; i; i = i->next) {
		alpm_graph_t *vertex_i = i->data;
		alpm_pkg_t *p_i = vertex_i->data;
		/* TODO this should be somehow combined with alpm_checkdeps */
		for(j = vertices; j; j = j->next) {
			alpm_graph_t *vertex_j = j->data;
			alpm_pkg_t *p_j = vertex_j->data;
			if(_alpm_pkg_depends_on(p_i, p_j)) {
				vertex_i->children =
					alpm_list_add(vertex_i->children, vertex_j);
			}
		}

		/* lazily add local packages to the dep graph so they don't
		 * get resolved unnecessarily */
		j = localpkgs;
		while(j) {
			alpm_list_t *next = j->next;
			if(_alpm_pkg_depends_on(p_i, j->data)) {
				alpm_graph_t *vertex_j = _alpm_graph_new();
				vertex_j->data = (void *)j->data;
				vertices = alpm_list_add(vertices, vertex_j);
				vertex_i->children =
					alpm_list_add(vertex_i->children, vertex_j);
				localpkgs = alpm_list_remove_item(localpkgs, j);
				free(j);
			}
			j = next;
		}

		vertex_i->childptr = vertex_i->children;
	}
	alpm_list_free(localpkgs);
	return vertices;
}
コード例 #3
0
ファイル: pkghash.c プロジェクト: JohnFrazier/pacman
/**
 * @brief Remove a package from a pkghash.
 *
 * @param hash     the hash to remove the package from
 * @param pkg      the package we are removing
 * @param data     output parameter containing the removed item
 *
 * @return the resultant hash
 */
alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg,
		alpm_pkg_t **data)
{
	alpm_list_t *i;
	unsigned int position;

	if(data) {
		*data = NULL;
	}

	if(pkg == NULL || hash == NULL) {
		return hash;
	}

	position = pkg->name_hash % hash->buckets;
	while((i = hash->hash_table[position]) != NULL) {
		alpm_pkg_t *info = i->data;

		if(info->name_hash == pkg->name_hash &&
					strcmp(info->name, pkg->name) == 0) {
			unsigned int stop, prev;

			/* remove from list and hash */
			hash->list = alpm_list_remove_item(hash->list, i);
			if(data) {
				*data = info;
			}
			hash->hash_table[position] = NULL;
			free(i);
			hash->entries -= 1;

			/* Potentially move entries following removed entry to keep open
			 * addressing collision resolution working. We start by finding the
			 * next null bucket to know how far we have to look. */
			stop = position + stride;
			while(stop >= hash->buckets) {
				stop -= hash->buckets;
			}
			while(hash->hash_table[stop] != NULL && stop != position) {
				stop += stride;
				while(stop >= hash->buckets) {
					stop -= hash->buckets;
				}
			}
			stop = (hash->buckets + stop - stride) % hash->buckets;

			/* We now search backwards from stop to position. If we find an
			 * item that now hashes to position, we will move it, and then try
			 * to plug the new hole we just opened up, until we finally don't
			 * move anything. */
			while((prev = move_one_entry(hash, position, stop)) != position) {
				position = prev;
			}

			return hash;
		}

		position += stride;
		while(position >= hash->buckets) {
			position -= hash->buckets;
		}
	}

	return hash;
}