/* missing.c: * **************************************************************** * Copyright (C) 2003 Tom Lord * Portions (C) 2003 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/char/str.h" #include "libarch/namespace.h" #include "libarch/patch-logs.h" #include "libarch/missing.h" /* __STDC__ prototypes for static functions */ static int is_a_patch_present (rel_table has, t_uchar *log); static rel_table get_all_arch_logs (t_uchar *tree_root); static rel_table filter_present_logs (t_uchar * tree_root, struct arch_archive * arch, t_uchar * version,rel_table unfiltered); rel_table arch_missing (t_uchar const * tree_root, struct arch_archive * arch, t_uchar const * version, int skip_present) { rel_table has = 0; rel_table needs = 0; rel_table answer = 0; invariant (arch_valid_package_name (version, arch_no_archive, arch_req_version, 0)); has = arch_logs (tree_root, arch->official_name, version, 0); needs = arch_archive_revisions (arch, version, 0); rel_sort_table_by_field (0, has, 0); rel_sort_table_by_field (0, needs, 0); answer = rel_join (2, rel_join_output (2,0, -1), 0, 0, has, needs); arch_sort_table_by_patch_level_field (0, answer, 0); if (skip_present) answer = filter_present_logs((t_uchar *)tree_root, arch, (t_uchar *)version, answer); rel_free_table (has); rel_free_table (needs); return answer; } static int is_a_patch_present (rel_table has, t_uchar *log) { assoc_table headers = 0; t_uchar * new_patches_header; rel_table new_patches = 0; rel_table result = 0; int found = 0; arch_parse_log (0, &headers, 0, log); new_patches_header = assoc_ref (headers, "new-patches"); new_patches = rel_ws_split (new_patches_header); rel_sort_table_by_field (0, new_patches, 0); rel_uniq_by_field (&new_patches, 0); result = rel_join (-1, rel_join_output(1,0,2,0,-1), 0, 0, has, new_patches); if (rel_n_records (result) > 0) found = 1; free_assoc_table (headers); rel_free_table (new_patches); rel_free_table (result); return found; } static rel_table get_all_arch_logs (t_uchar *tree_root) { rel_table versions = 0; rel_table result = 0; int x; versions = arch_log_versions (tree_root,0,0,0,0); for (x = 0; x < rel_n_records (versions); ++x) { rel_table version_logs = 0; t_uchar * archive; t_uchar * revision; archive = arch_parse_package_name (arch_ret_archive, 0 , versions[x][0]); revision = arch_parse_package_name (arch_ret_non_archive, 0, versions[x][0]); version_logs = arch_logs (tree_root, archive, revision, 1); rel_append_x (&result, version_logs); lim_free (0, revision); lim_free (0, archive); rel_free_table (version_logs); } rel_free_table (versions); rel_sort_table_by_field (0, result, 0); return result; } static rel_table filter_present_logs (t_uchar * tree_root, struct arch_archive * arch, t_uchar * version,rel_table unfiltered) { rel_table has = 0; rel_table to_skip = 0; rel_table answer = 0; int x; if (rel_n_records (unfiltered) < 1) return unfiltered; has = get_all_arch_logs (tree_root); for (x = 0; x < rel_n_records (unfiltered); ++x) { t_uchar * revision = str_alloc_cat_many (0, version, "--", unfiltered[x][0], str_end); t_uchar * log = 0; log = arch_archive_log (arch, revision); if (is_a_patch_present(has, log)) rel_add_records (&to_skip, rel_copy_record (unfiltered[x]), 0); lim_free (0, revision); } rel_free_table (has); rel_sort_table_by_field (0, to_skip, 0); rel_sort_table_by_field (0, unfiltered, 0); answer = rel_join (1, rel_join_output (1,0, -1), 0, 0, unfiltered, to_skip); arch_sort_table_by_patch_level_field (0, answer, 0); rel_free_table (unfiltered); rel_free_table (to_skip); return answer; } /* tag: Tom Lord Sat May 24 23:01:13 2003 (whats-missing.c) */