/* inventory-file.c: * * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2 **************************************************************** * Copyright (C) 2005 Canonical Limited * Authors: Robert Collins * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #include "hackerlab/bugs/panic.h" #include "hackerlab/vu/safe.h" #include "hackerlab/fs/cwd.h" #include "hackerlab/fs/file-names.h" #include "hackerlab/char/str.h" #include "po/gettext.h" #include "libfsutils/file-contents.h" #include "libawk/trim.h" #include "libarch/ancestry.h" #include "libarch/namespace.h" #include "libarch/patch-id.h" #include "libarch/patch-logs.h" #include "libarch/changelogs.h" #include "libarch/inv-ids.h" #include "libarch/invent.h" #include "libarch/project-tree.h" #include "libarch/debug.h" #include "libarch/inventory-entry.h" inventory_entry_vtable_t inventory_file_vtable = { NULL, NULL, arch_project_tree_vtable_end }; static inventory_entry_t * inventory_dir_add_child (inventory_entry_t * entry, inventory_entry_t * child); static inventory_entry_t * inventory_dir_get_child (inventory_entry_t * entry, t_uchar const * const name); inventory_entry_vtable_t inventory_dir_vtable = { inventory_dir_add_child, inventory_dir_get_child, arch_project_tree_vtable_end }; inventory_file_t * inventory_file_new (inventory_file_t * parent, t_uchar const * const name, t_uchar const * const id) { inventory_file_t *result = talloc (NULL, inventory_file_t); inventory_file_init (result, parent, name, id); result->vtable = &inventory_file_vtable; return result; } void inventory_file_init (inventory_file_t * file, inventory_file_t * parent, t_uchar const * const name, t_uchar const * const id) { file->vtable = &inventory_file_vtable; file->name = talloc_strdup (file, name); file->id = talloc_strdup (file, id); if (parent) file->parent = inventory_entry_add_child (parent, file) ? parent : NULL; else file->parent = NULL; } int inventory_file_finalise (void *data) { /* all resources auto freed */ return 0; } inventory_entry_t * inventory_dir_new (inventory_file_t * parent, t_uchar const * const name, t_uchar const * const id) { inventory_dir_t *result = talloc (NULL, inventory_dir_t); talloc_set_destructor (result, inventory_dir_finalise); inventory_file_init (&result->entry, parent, name, id); result->children = NULL; result->entry.vtable = &inventory_dir_vtable; return &result->entry; } int inventory_dir_finalise (void *data) { inventory_dir_t *dir = (inventory_dir_t *)data; /* children are auto freed, but the array isn't */ ar_free_inventory_entry (&dir->children); inventory_file_finalise (&dir->entry); return 0; } /** * \brief get the child of an inventory item. for files this always returns NULL */ inventory_entry_t * inventory_entry_get_child (inventory_entry_t * entry, t_uchar const * const name) { invariant (!!entry->vtable); if (!entry->vtable->get_child) return NULL; return entry->vtable->get_child (entry, name); } /** * \brief get the child of an inventory item. for files this always returns NULL * \return the added child - if this is not returned, the add failed */ inventory_entry_t * inventory_entry_add_child (inventory_entry_t * entry, inventory_entry_t *child) { invariant (!!entry->vtable); if (!entry->vtable->add_child) return NULL; return entry->vtable->add_child (entry, child); } inventory_file_t * inventory_dir_get_child (inventory_file_t * file, t_uchar const * const name) { inventory_dir_t *dir = talloc_get_type (file, inventory_dir_t); int index; invariant (!!dir); debug (dbg_invent, 9, _("Looking for child '%s' under id '%s' (%d) elements\n"), name, file->id, ar_size_inventory_entry (dir->children)); ar_for_each (dir->children, index) if (!str_cmp (name, dir->children[index]->name)) return dir->children[index]; return NULL; } inventory_file_t * inventory_dir_add_child (inventory_file_t * file, inventory_file_t * child) { inventory_dir_t *dir = talloc_get_type (file, inventory_dir_t); invariant (!!dir); debug (dbg_invent, 9, _("Adding child '%s' under id '%s' (%d) elements\n"), child->name, file->id, ar_size_inventory_entry (dir->children)); if (inventory_dir_get_child (file, child->name)) /* already present */ return NULL; ar_push_inventory_entry (&dir->children, child); return child; } inventory_entry_t * inventory_link_new (inventory_file_t * parent, t_uchar const * const name, t_uchar const * const id) { inventory_link_t *result = talloc (NULL, inventory_link_t); talloc_set_destructor (result, inventory_link_finalise); inventory_file_init (&result->entry, parent, name, id); result->entry.vtable = &inventory_file_vtable; return &result->entry; } int inventory_link_finalise (void *data) { /* all resources auto freed */ return 0; }