Di_packages

## Data Structures

struct | di_packages
| Packages file. More...
struct | di_packages_allocator
| Packages file - Allocator. More...
struct | di_packages_resolve_dependencies_check
struct | di_packages_resolve_dependencies_do_real_list_append_data

## Typedefs

typedef bool | di_packages_resolve_dependencies_check_package(di_packages_resolve_dependencies_check *r, di_package *package, di_package_dependency *d)
typedef di_package_dependency * | di_packages_resolve_dependencies_check_provide(di_package *package, di_package_dependency *best, di_package_dependency *d, void *data)
typedef void | di_packages_resolve_dependencies_do_package(di_package *package, void *data)

## Functions

di_packages * | di_packages_alloc (void)
void | di_packages_free (di_packages *packages)
di_packages_allocator * | di_packages_allocator_alloc (void)
void | di_packages_allocator_free (di_packages_allocator *packages)
void | di_packages_append_package (di_packages *packages, di_package *package, di_packages_allocator *allocator)
di_package * | di_packages_get_package (di_packages *packages, const char *name, size_t n)
di_package * | di_packages_get_package_new (di_packages *packages, di_packages_allocator *allocator, char *name, size_t n)
di_slist * | di_packages_resolve_dependencies (di_packages *packages, di_slist *list, di_packages_allocator *allocator)
di_slist * | di_packages_resolve_dependencies_array (di_packages *packages, di_package **array, di_packages_allocator *allocator)
void | di_packages_resolve_dependencies_mark (di_packages *packages)
di_packages_allocator * | internal_di_packages_allocator_alloc (void)
di_slist * | di_packages_resolve_dependencies_special (di_packages *packages, di_slist *list, di_packages_resolve_dependencies_check *s, di_packages_allocator *allocator)
di_slist * | di_packages_resolve_dependencies_array_special (di_packages *packages, di_package **array, di_packages_resolve_dependencies_check *s, di_packages_allocator *allocator)
void | di_packages_resolve_dependencies_mark_special (di_packages *packages, di_packages_resolve_dependencies_check *s)
void | di_packages_resolve_dependencies_marker (di_packages *packages)
bool | di_packages_resolve_dependencies_recurse (di_packages_resolve_dependencies_check *r, di_package *package, di_package *dependend_package)

## Variables

di_packages_resolve_dependencies_check_package | di_packages_resolve_dependencies_check_real
di_packages_resolve_dependencies_check_package | di_packages_resolve_dependencies_check_non_existant
di_packages_resolve_dependencies_check_package | di_packages_resolve_dependencies_check_non_existant_quiet
di_packages_resolve_dependencies_check_package | di_packages_resolve_dependencies_check_non_existant_permissive
di_packages_resolve_dependencies_check_provide | di_packages_resolve_dependencies_check_virtual
di_packages_resolve_dependencies_do_package | di_packages_resolve_dependencies_do_real_list_append
di_packages_resolve_dependencies_do_package | di_packages_resolve_dependencies_do_real_mark

## Detailed Description

## Function Documentation

## di_packages_alloc()

di_packages * di_packages_alloc | ( | void |  | ) |

Allocate di_packages

{
di_packages *ret;
ret = di_new0 (di_packages, 1);
ret->table = di_hash_table_new_full (di_rstring_hash, di_rstring_equal, NULL, internal_di_package_destroy_func);
return ret;
}
di_hash_table_new_full
di_hash_table * di_hash_table_new_full(di_hash_func hash_func, di_equal_func key_equal_func, di_destroy_notify key_destroy_func, di_destroy_notify value_destroy_func)
Definition hash.c:113
di_new0
#define di_new0(struct_type, n_structs)
Definition mem.h:79
internal_di_package_destroy_func
di_destroy_notify internal_di_package_destroy_func
Definition package_internal.h:80
di_packages
Packages file.
Definition packages.h:42
di_packages::table
di_hash_table * table
Definition packages.h:43

References di_hash_table_new_full(), di_new0, internal_di_package_destroy_func, and table.

## di_packages_allocator_alloc()

di_packages_allocator * di_packages_allocator_alloc | ( | void |  | ) |

Allocate di_packages_allocator

{
di_packages_allocator *ret;
ret = internal_di_packages_allocator_alloc ();
ret->package_mem_chunk = di_mem_chunk_new (sizeof (di_package), 16384);
return ret;
}
di_mem_chunk_new
di_mem_chunk * di_mem_chunk_new(di_ksize_t atom_size, di_ksize_t area_size)
Definition mem_chunk.c:87
internal_di_packages_allocator_alloc
di_packages_allocator * internal_di_packages_allocator_alloc(void)
Definition packages.c:62
di_package
Package.
Definition package.h:96
di_packages_allocator
Packages file - Allocator.
Definition packages.h:53
di_packages_allocator::package_mem_chunk
di_mem_chunk * package_mem_chunk
Definition packages.h:54

References di_mem_chunk_new(), internal_di_packages_allocator_alloc(), and di_packages_allocator::package_mem_chunk.

## di_packages_allocator_free()

void di_packages_allocator_free | ( | di_packages_allocator * | allocator | ) |

Free di_packages_allocator

{
di_mem_chunk_destroy (allocator->package_mem_chunk);
di_mem_chunk_destroy (allocator->package_dependency_mem_chunk);
di_mem_chunk_destroy (allocator->slist_node_mem_chunk);
di_free (allocator);
}
di_free
void di_free(void *mem)
Definition mem.c:60
di_packages_allocator::slist_node_mem_chunk
di_mem_chunk * slist_node_mem_chunk
Definition packages.h:56
di_packages_allocator::package_dependency_mem_chunk
di_mem_chunk * package_dependency_mem_chunk
Definition packages.h:55

References di_free(), di_packages_allocator::package_dependency_mem_chunk, di_packages_allocator::package_mem_chunk, and di_packages_allocator::slist_node_mem_chunk.

## di_packages_append_package()

void di_packages_append_package | ( | di_packages * | packages,
|  | di_package * | package,
|  | di_packages_allocator * | allocator
| ) |  |

append a package.

Parameters

  packages | a di_packages

{
di_package *tmp;
tmp = di_packages_get_package (packages, package->package, 0);
if (!tmp)
di_slist_append_chunk (&packages->list, package, allocator->slist_node_mem_chunk);
di_hash_table_insert (packages->table, &package->key, package);
}
di_hash_table_insert
void di_hash_table_insert(di_hash_table *hash_table, void *key, void *value)
Definition hash.c:178
di_packages_get_package
di_package * di_packages_get_package(di_packages *packages, const char *name, size_t n)
Definition packages.c:121
di_slist_append_chunk
void di_slist_append_chunk(di_slist *slist, void *data, di_mem_chunk *mem_chunk) __attribute__((nonnull(1
di_package::key
di_rstring key
Definition package.h:100
di_package::package
char * package
Definition package.h:99
di_packages::list
di_slist list
Definition packages.h:44

References di_hash_table_insert(), di_packages_get_package(), di_slist_append_chunk(), di_package::key, list, di_package::package, di_packages_allocator::slist_node_mem_chunk, and table.

## di_packages_free()

void di_packages_free | ( | di_packages * | packages | ) |

Free di_packages

{
if (!packages)
return;
di_hash_table_destroy (packages->table);
di_free (packages);
}
di_hash_table_destroy
void di_hash_table_destroy(di_hash_table *hash_table)
Definition hash.c:134

References di_free(), di_hash_table_destroy(), and table.

## di_packages_get_package()

di_package * di_packages_get_package | ( | di_packages * | packages,
|  | const char * | name,
|  | size_t | n
| ) |  |

get a named package.

Parameters

  packages | a di_packages
  name | the name of the package
  n | size of the name or 0

Returns
  the package or NULL

{
di_rstring key;
size_t size;
if (n)
size = n;
else
size = strlen (name);
/* i know that is bad, but i know it is not written by the lookup */
key.string = (char *) name;
key.size = size;
return di_hash_table_lookup (packages->table, &key);
}
di_hash_table_lookup
void * di_hash_table_lookup(di_hash_table *hash_table, const void *key)
Definition hash.c:169
di_rstring
raw string
Definition string.h:38
di_rstring::size
di_ksize_t size
Definition string.h:40
di_rstring::string
char * string
Definition string.h:39

References di_hash_table_lookup(), di_rstring::size, di_rstring::string, and table.

Referenced by di_packages_append_package(), and di_packages_get_package_new().

## di_packages_get_package_new()

di_package * di_packages_get_package_new | ( | di_packages * | packages,
|  | di_packages_allocator * | allocator,
|  | char * | name,
|  | size_t | n
| ) |  |

get a named package. creates a new one if non-existant.

Parameters

  packages | a di_packages
  name | the name of the package
  n | size of the name

Returns
  the package

{
di_package *ret = di_packages_get_package (packages, name, n);
if (!ret)
{
ret = di_package_alloc (allocator);
ret->key.string = di_stradup (name, n);
ret->key.size = n;
di_hash_table_insert (packages->table, &ret->key, ret);
}
return ret;
}
di_stradup
char * di_stradup(const char *s, size_t n)
Definition string.c:45

References di_hash_table_insert(), di_packages_get_package(), di_stradup(), di_package::key, di_rstring::size, di_rstring::string, and table.

## di_packages_resolve_dependencies()

di_slist * di_packages_resolve_dependencies | ( | di_packages * | packages,
|  | di_slist * | list,
|  | di_packages_allocator * | allocator
| ) |  |

{
struct di_packages_resolve_dependencies_check s =
{
di_packages_resolve_dependencies_check_real,
di_packages_resolve_dependencies_check_virtual,
di_packages_resolve_dependencies_check_non_existant,
di_packages_resolve_dependencies_do_real_list_append,
0,
NULL,
NULL,
};
return di_packages_resolve_dependencies_special (packages, list, &s, allocator);
}
di_packages_resolve_dependencies_check
Definition packages_internal.h:41

## di_packages_resolve_dependencies_array()

di_slist * di_packages_resolve_dependencies_array | ( | di_packages * | packages,
|  | di_package ** | array,
|  | di_packages_allocator * | allocator
| ) |  |

{
struct di_packages_resolve_dependencies_check s =
{
di_packages_resolve_dependencies_check_real,
di_packages_resolve_dependencies_check_virtual,
di_packages_resolve_dependencies_check_non_existant,
di_packages_resolve_dependencies_do_real_list_append,
0,
NULL,
NULL,
};
return di_packages_resolve_dependencies_array_special (packages, array, &s, allocator);
}

## di_packages_resolve_dependencies_array_special()

di_slist * di_packages_resolve_dependencies_array_special | ( | di_packages * | packages,
|  | di_package ** | array,
|  | di_packages_resolve_dependencies_check * | s,
|  | di_packages_allocator * | allocator
| ) |  |

{
struct di_packages_resolve_dependencies_do_real_list_append_data data =
{
{ NULL, NULL },
allocator,
};
di_slist *install = di_slist_alloc ();
s->do_real_data = &data;
di_packages_resolve_dependencies_marker (packages);
s->resolver = packages->resolver;
while (*array)
if (di_packages_resolve_dependencies_recurse (s, *array++, NULL))
internal_di_slist_append_list (install, &data.list);
return install;
}
internal_di_slist_append_list
void internal_di_slist_append_list(di_slist *slist, di_slist *slist_append)
Definition slist.c:99
di_slist_alloc
di_slist * di_slist_alloc(void)
Definition slist.c:26
di_packages_resolve_dependencies_do_real_list_append_data
Definition packages_internal.h:72
di_packages::resolver
unsigned int resolver
Definition packages.h:45
di_slist
Single-linked list.
Definition slist.h:37

## di_packages_resolve_dependencies_mark()

void di_packages_resolve_dependencies_mark | ( | di_packages * | packages | ) |

{
struct di_packages_resolve_dependencies_check s =
{
di_packages_resolve_dependencies_check_real,
di_packages_resolve_dependencies_check_virtual,
di_packages_resolve_dependencies_check_non_existant_quiet,
di_packages_resolve_dependencies_do_real_mark,
0,
NULL,
NULL,
};
di_packages_resolve_dependencies_mark_special (packages, &s);
}

## di_packages_resolve_dependencies_mark_special()

void di_packages_resolve_dependencies_mark_special | ( | di_packages * | packages,
|  | di_packages_resolve_dependencies_check * | s
| ) |  |

{
di_slist_node *node;
di_packages_resolve_dependencies_marker (packages);
s->resolver = packages->resolver;
for (node = packages->list.head; node; node = node->next)
{
di_package *package = node->data;
if (!(package->resolver & packages->resolver) && package->status_want == di_package_status_want_install)
di_packages_resolve_dependencies_recurse (s, package, NULL);
}
}
di_slist_node
Node of a single-linked list.
Definition slist.h:46
di_slist_node::next
di_slist_node * next
Definition slist.h:47
di_slist::head
di_slist_node * head
Definition slist.h:38

## di_packages_resolve_dependencies_marker()

void di_packages_resolve_dependencies_marker | ( | di_packages * | packages | ) |

{
if (!packages->resolver)
packages->resolver = 1;
else if (packages->resolver > (INT_MAX >> 2))
{
di_hash_table_foreach (packages->table, resolve_dependencies_marker_reset, NULL);
packages->resolver = 1;
}
else
packages->resolver <<= 3;
}
di_hash_table_foreach
void di_hash_table_foreach(di_hash_table *hash_table, di_hfunc *func, void *user_data)
Definition hash.c:246

## di_packages_resolve_dependencies_recurse()

bool di_packages_resolve_dependencies_recurse | ( | di_packages_resolve_dependencies_check * | r,
|  | di_package * | package,
|  | di_package * | dependend_package
| ) |  |

{
di_slist_node *node;
/* did we already check this package? */
if (package->resolver & r->resolver)
{
#ifdef ENABLE_EXTENSIVE_DEBUG
if (package->resolver & (r->resolver << 1))
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): already done, okay", package->package);
else
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): already done, not okay", package->package);
#endif
return package->resolver & (r->resolver << 1);
}
package->resolver |= r->resolver;
package->resolver |= (r->resolver << 1);
#ifdef ENABLE_EXTENSIVE_DEBUG
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): start", package->package);
#endif
switch (package->type)
{
case di_package_type_real_package:
for (node = package->depends.head; node; node = node->next)
{
di_package_dependency *d = node->data;
if ((d->type == di_package_dependency_type_depends ||
d->type == di_package_dependency_type_pre_depends) &&
!r->check_real (r, package, d))
goto error;
}
#ifdef ENABLE_EXTENSIVE_DEBUG
if (dependend_package)
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): mark, dependency from %s", package->package, dependend_package->package);
else
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): mark", package->package);
#endif
r->do_real (package, r->do_real_data);
break;
case di_package_type_virtual_package:
#ifdef ENABLE_EXTENSIVE_DEBUG
if (dependend_package)
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): search, dependency from %s", package->package, dependend_package->package);
else
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): search", package->package);
#endif
for (node = package->depends.head; node; node = node->next)
{
di_package_dependency *d = node->data;
if (d->type == di_package_dependency_type_reverse_provides)
package->resolver &= ~(r->resolver << 2);
}
while (1)
{
di_package_dependency *best_provide = NULL;
for (node = package->depends.head; node; node = node->next)
{
di_package_dependency *d = node->data;
if (d->type == di_package_dependency_type_reverse_provides)
{
if (!(package->resolver & (r->resolver << 2)))
best_provide = r->check_virtual (package, best_provide, d, r->check_virtual_data);
}
}
if (best_provide)
{
if (r->check_real (r, dependend_package, best_provide))
break;
else
package->resolver |= (r->resolver << 2);
}
else if (!r->check_non_existant (r, package, NULL))
goto error;
else
break;
}
break;
case di_package_type_non_existent:
if (!r->check_non_existant (r, package, NULL))
goto error;
}
return true;
error:
#ifdef ENABLE_EXTENSIVE_DEBUG
di_log (DI_LOG_LEVEL_DEBUG, "resolver (%s): not okay", package->package);
#endif
package->resolver &= ~(r->resolver << 1);
return false;
}
di_log
void di_log(di_log_level_flags log_level, const char *format,...) __attribute__((format(printf
DI_LOG_LEVEL_DEBUG
@ DI_LOG_LEVEL_DEBUG
Definition log.h:42
di_package_type_virtual_package
@ di_package_type_virtual_package
Definition package.h:88
di_package_type_real_package
@ di_package_type_real_package
Definition package.h:89
di_package_type_non_existent
@ di_package_type_non_existent
Definition package.h:87
di_package_dependency_type_pre_depends
@ di_package_dependency_type_pre_depends
Definition package.h:129
di_package_dependency_type_depends
@ di_package_dependency_type_depends
Definition package.h:128
di_package_dependency_type_reverse_provides
@ di_package_dependency_type_reverse_provides
Definition package.h:134
di_package_dependency
Package dependency.
Definition package.h:142
di_package_dependency::type
di_package_dependency_type type
Definition package.h:143
di_package::depends
di_slist depends
Definition package.h:112
di_package::resolver
unsigned int resolver
Definition package.h:118
di_package::type
di_package_type type
Definition package.h:102
di_slist_node::data
void * data
Definition slist.h:48

## di_packages_resolve_dependencies_special()

di_slist * di_packages_resolve_dependencies_special | ( | di_packages * | packages,
|  | di_slist * | list,
|  | di_packages_resolve_dependencies_check * | s,
|  | di_packages_allocator * | allocator
| ) |  |

{
struct di_packages_resolve_dependencies_do_real_list_append_data data =
{
{ NULL, NULL },
allocator,
};
di_slist *install = di_slist_alloc ();
di_slist_node *node;
s->do_real_data = &data;
di_packages_resolve_dependencies_marker (packages);
s->resolver = packages->resolver;
for (node = list->head; node; node = node->next)
{
di_package *p = node->data;
if (di_packages_resolve_dependencies_recurse (s, p, NULL))
internal_di_slist_append_list (install, &data.list);
}
return install;
}

## internal_di_packages_allocator_alloc()

di_packages_allocator * internal_di_packages_allocator_alloc | ( | void |  | ) |

Partially allocate di_packages_allocator

{
di_packages_allocator *ret;
ret = di_new0 (di_packages_allocator, 1);
ret->package_dependency_mem_chunk = di_mem_chunk_new (sizeof (di_package_dependency), 4096);
ret->slist_node_mem_chunk = di_mem_chunk_new (sizeof (di_slist_node), 4096);
return ret;
}

References di_mem_chunk_new(), di_new0, di_packages_allocator::package_dependency_mem_chunk, and di_packages_allocator::slist_node_mem_chunk.

Referenced by di_packages_allocator_alloc().