/* merge-points.c: * **************************************************************** * Copyright (C) 2003 Tom Lord * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #include "hackerlab/bugs/panic.h" #include "hackerlab/mem/alloc-limits.h" #include "hackerlab/char/str.h" #include "hackerlab/vu/safe.h" #include "libfsutils/file-contents.h" #include "libarch/patch-logs.h" #include "libarch/namespace.h" #include "libarch/merge-points.h" /* __STDC__ prototypes for static functions */ static void arch_add_merge_points (rel_table * out, t_uchar * level, t_uchar * log, t_uchar * prefix); static t_uchar * arch_merge_points_prefix (t_uchar * from_archive, t_uchar * from_spec); rel_table arch_tree_merge_points (t_uchar * tree_root, t_uchar * into_archive, t_uchar * into_spec, t_uchar * from_archive, t_uchar * from_spec) { rel_table answer = 0; rel_table source_logs = 0; int x; t_uchar * prefix = 0; if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_patch_level, 0)) { t_uchar * path = 0; t_uchar * level = 0; path = arch_log_file (tree_root, into_archive, into_spec); level = arch_parse_package_name (arch_ret_patch_level, 0, into_spec); rel_add_records (&source_logs, rel_make_record (into_spec, path, 0), 0); lim_free (0, path); lim_free (0, level); } else if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_version, 0)) { source_logs = arch_logs (tree_root, into_archive, into_spec, 0); } else panic ("invalid into_spec argument to arch_tree_merge_points"); prefix = arch_merge_points_prefix (from_archive, from_spec); for (x = 0; x < rel_n_records (source_logs); ++x) { t_uchar * log_text = 0; log_text = file_contents (source_logs[x][1]); arch_add_merge_points (&answer, source_logs[x][0], log_text, prefix); lim_free (0, log_text); } rel_free_table (source_logs); lim_free (0, prefix); return answer; } rel_table arch_archive_merge_points (struct arch_archive * into_arch, t_uchar * into_spec, t_uchar * from_archive, t_uchar * from_spec, int upto) { rel_table answer = 0; rel_table source_revisions = 0; int x; t_uchar * prefix = 0; if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_patch_level, 0)) { if (!upto) rel_add_records (&source_revisions, rel_make_record (into_spec, 0), 0); else { t_uchar * into_version = 0; rel_table all_source_revisions = 0; into_version = arch_parse_package_name (arch_ret_package_version, 0, into_spec); all_source_revisions = arch_archive_revisions (into_arch, into_version, 2); for (x = 0; x < rel_n_records (all_source_revisions); ++x) { rel_add_records (&source_revisions, rel_copy_record (all_source_revisions[x]), 0); if (!str_cmp (all_source_revisions[x][0], into_spec)) break; } if (x == rel_n_records (all_source_revisions)) { safe_printfmt (2, "arch: attempt to compute merge-points of non-existent revision\n (%s\%s)\n", into_arch->official_name, into_spec); exit (2); } lim_free (0, into_version); rel_free_table (all_source_revisions); } } else if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_version, 0)) { source_revisions = arch_archive_revisions (into_arch, into_spec, 2); } else panic ("invalid into_spec argument to arch_archive_merge_points"); prefix = arch_merge_points_prefix (from_archive, from_spec); for (x = 0; x < rel_n_records (source_revisions); ++x) { t_uchar * log_text = 0; t_uchar * level = 0; log_text = arch_archive_log (into_arch, source_revisions[x][0]); level = arch_parse_package_name (arch_ret_patch_level, 0, source_revisions[x][0]); arch_add_merge_points (&answer, level, log_text, prefix); lim_free (0, log_text); lim_free (0, level); } rel_free_table (source_revisions); lim_free (0, prefix); return answer; } rel_table arch_new_in_version (t_uchar * tree_root, t_uchar * archive, t_uchar * version) { rel_table merge_points = 0; rel_table all_logs = 0; rel_table answer = 0; merge_points = arch_tree_merge_points (tree_root, archive, version, 0, 0); all_logs = arch_all_logs (tree_root); rel_sort_table_by_field (0, merge_points, 1); rel_sort_table_by_field (0, all_logs, 0); answer = rel_join (2, rel_join_output (2,0, -1), 1, 0, merge_points, all_logs); arch_sort_table_by_name_field (0, answer, 0); rel_free_table (merge_points); rel_free_table (all_logs); return answer; } /* find all tree logs that are in tree and not in reference_tree * TODO tests ! */ rel_table arch_new_in_tree (arch_project_tree_t *tree, t_uchar *reference_tree_root) { rel_table all_logs = 0; rel_table reference_logs = 0; rel_table answer = 0; all_logs = arch_all_logs (tree->root); reference_logs = arch_all_logs (reference_tree_root); rel_sort_table_by_field (0, all_logs, 0); rel_sort_table_by_field (0, reference_logs, 0); answer = rel_join (2, rel_join_output (2,0, -1), 0, 0, reference_logs, all_logs); arch_sort_table_by_name_field (0, answer, 0); rel_free_table (reference_logs); rel_free_table (all_logs); return answer; } static void arch_add_merge_points (rel_table * out, t_uchar * level, t_uchar * log, t_uchar * prefix) { assoc_table headers = 0; t_uchar * new_patches_header; rel_table new_patches = 0; int x; arch_parse_log (0, &headers, 0, log); new_patches_header = assoc_ref (headers, "new-patches"); new_patches = rel_ws_split (new_patches_header); arch_sort_table_by_name_field (0, new_patches, 0); rel_uniq_by_field (&new_patches, 0); for (x = 0; x < rel_n_records (new_patches); ++x) { if (!str_cmp_prefix (prefix, new_patches[x][0])) rel_add_records (out, rel_make_record (level, new_patches[x][0], 0), 0); } free_assoc_table (headers); rel_free_table (new_patches); } static t_uchar * arch_merge_points_prefix (t_uchar * from_archive, t_uchar * from_spec) { if (!from_archive) return 0; else if (arch_valid_package_name (from_spec, arch_no_archive, arch_req_patch_level, 0)) return arch_fully_qualify (from_archive, from_spec); else return str_alloc_cat_many (0, from_archive, "/", from_spec, "--", str_end); } /* tag: Tom Lord Tue May 27 18:04:17 2003 (merge-points.c) */