1 /* merge-points.c:
2 *
3 ****************************************************************
4 * Copyright (C) 2003 Tom Lord
5 *
6 * See the file "COPYING" for further information about
7 * the copyright and warranty status of this work.
8 */
9
10
11 #include "hackerlab/bugs/panic.h"
12 #include "hackerlab/mem/alloc-limits.h"
13 #include "hackerlab/char/str.h"
14 #include "hackerlab/vu/safe.h"
15 #include "tla/libfsutils/file-contents.h"
16 #include "tla/libarch/patch-logs.h"
17 #include "tla/libarch/namespace.h"
18 #include "tla/libarch/merge-points.h"
19
20
21 /* __STDC__ prototypes for static functions */
22 static void arch_add_merge_points (rel_table * out,
23 const t_uchar * level,
24 const t_uchar * log,
25 const t_uchar * prefix);
26 static t_uchar * arch_merge_points_prefix (const t_uchar * from_archive,
27 const t_uchar * from_spec);
28
29
30
31 rel_table
arch_tree_merge_points(const t_uchar * tree_root,const t_uchar * into_archive,const t_uchar * into_spec,const t_uchar * from_archive,const t_uchar * from_spec)32 arch_tree_merge_points (const t_uchar * tree_root,
33 const t_uchar * into_archive,
34 const t_uchar * into_spec,
35 const t_uchar * from_archive,
36 const t_uchar * from_spec)
37 {
38 rel_table answer = rel_table_nil;
39 rel_table source_logs = rel_table_nil;
40 int x;
41 t_uchar * prefix = 0;
42
43 if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_patch_level, 0))
44 {
45 t_uchar * path = 0;
46 t_uchar * level = 0;
47
48 path = arch_log_file (tree_root, into_archive, into_spec);
49 level = arch_parse_package_name (arch_ret_patch_level, 0, into_spec);
50
51 rel_add_records (&source_logs, rel_make_record_2_taking (rel_make_field_str (into_spec), rel_make_field_str (path)), rel_record_null);
52
53 lim_free (0, path);
54 lim_free (0, level);
55 }
56 else if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_version, 0))
57 {
58 source_logs = arch_logs (tree_root, into_archive, into_spec, 0);
59 }
60 else
61 panic ("invalid into_spec argument to arch_tree_merge_points");
62
63 prefix = arch_merge_points_prefix (from_archive, from_spec);
64
65 for (x = 0; x < rel_n_records (source_logs); ++x)
66 {
67 t_uchar * log_text = 0;
68
69 log_text = file_contents (rel_peek_str (source_logs, x, 1));
70
71 arch_add_merge_points (&answer, rel_peek_str (source_logs, x, 0), log_text, prefix);
72
73 lim_free (0, log_text);
74 }
75
76
77 rel_free_table (source_logs);
78 lim_free (0, prefix);
79
80 return answer;
81 }
82
83
84 rel_table
arch_archive_merge_points(struct arch_archive * into_arch,const t_uchar * into_spec,const t_uchar * from_archive,const t_uchar * from_spec,int upto)85 arch_archive_merge_points (struct arch_archive * into_arch,
86 const t_uchar * into_spec,
87 const t_uchar * from_archive,
88 const t_uchar * from_spec,
89 int upto)
90 {
91 rel_table answer = rel_table_nil;
92 rel_table source_revisions = rel_table_nil;
93 int x;
94 t_uchar * prefix = 0;
95
96 if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_patch_level, 0))
97 {
98 if (!upto)
99 rel_add_records (&source_revisions, rel_singleton_record_taking (rel_make_field_str (into_spec)), rel_record_null);
100 else
101 {
102 t_uchar * into_version = 0;
103 rel_table all_source_revisions = rel_table_nil;
104
105 into_version = arch_parse_package_name (arch_ret_package_version, 0, into_spec);
106 all_source_revisions = arch_archive_revisions (into_arch, into_version, 2);
107 for (x = 0; x < rel_n_records (all_source_revisions); ++x)
108 {
109 rel_add_records (&source_revisions, rel_copy_record (rel_peek_record (all_source_revisions, x)), rel_record_null);
110 if (!str_cmp (rel_peek_str (all_source_revisions, x, 0), into_spec))
111 break;
112 }
113
114 if (x == rel_n_records (all_source_revisions))
115 {
116 safe_printfmt (2, "arch: attempt to compute merge-points of non-existent revision\n (%s\%s)\n", into_arch->name, into_spec);
117 exit (2);
118 }
119
120 lim_free (0, into_version);
121 rel_free_table (all_source_revisions);
122 }
123 }
124 else if (arch_valid_package_name (into_spec, arch_no_archive, arch_req_version, 0))
125 {
126 source_revisions = arch_archive_revisions (into_arch, into_spec, 2);
127 }
128 else
129 panic ("invalid into_spec argument to arch_archive_merge_points");
130
131
132 prefix = arch_merge_points_prefix (from_archive, from_spec);
133
134 for (x = 0; x < rel_n_records (source_revisions); ++x)
135 {
136 t_uchar * log_text = 0;
137 t_uchar * level = 0;
138
139 log_text = arch_archive_log (into_arch, rel_peek_str (source_revisions, x, 0));
140 level = arch_parse_package_name (arch_ret_patch_level, 0, rel_peek_str (source_revisions, x, 0));
141
142 arch_add_merge_points (&answer, level, log_text, prefix);
143
144 lim_free (0, log_text);
145 lim_free (0, level);
146 }
147
148
149 rel_free_table (source_revisions);
150 lim_free (0, prefix);
151
152 return answer;
153 }
154
155
156 rel_table
arch_new_in_version(const t_uchar * tree_root,const t_uchar * archive,const t_uchar * version)157 arch_new_in_version (const t_uchar * tree_root,
158 const t_uchar * archive,
159 const t_uchar * version)
160 {
161 rel_table merge_points = rel_table_nil;
162 rel_table all_logs = rel_table_nil;
163 rel_table answer = rel_table_nil;
164
165 merge_points = arch_tree_merge_points (tree_root, archive, version, 0, 0);
166 all_logs = arch_all_logs (tree_root);
167
168 rel_sort_table_by_field (0, merge_points, 1);
169 rel_sort_table_by_field (0, all_logs, 0);
170
171 answer = rel_join (2, rel_join_output (2,0, -1), 1, 0, merge_points, all_logs);
172 arch_sort_table_by_name_field (0, answer, 0);
173
174 rel_free_table (merge_points);
175 rel_free_table (all_logs);
176
177 return answer;
178 }
179
180
181
182
183 static void
arch_add_merge_points(rel_table * out,const t_uchar * level,const t_uchar * log,const t_uchar * prefix)184 arch_add_merge_points (rel_table * out,
185 const t_uchar * level,
186 const t_uchar * log,
187 const t_uchar * prefix)
188 {
189 assoc_table headers = 0;
190 const t_uchar * new_patches_header;
191 rel_table new_patches = rel_table_nil;
192 int x;
193
194 arch_parse_log (0, &headers, 0, log);
195 new_patches_header = assoc_get_str_taking (headers, rel_make_field_str ("new-patches"));
196
197 new_patches = rel_ws_split (new_patches_header);
198 arch_sort_table_by_name_field (0, new_patches, 0);
199 rel_uniq_by_field (&new_patches, 0);
200
201 for (x = 0; x < rel_n_records (new_patches); ++x)
202 {
203 if (!str_cmp_prefix (prefix, rel_peek_str (new_patches, x, 0)))
204 rel_add_records (out, rel_make_record_2_taking (rel_make_field_str (level), rel_get_field (new_patches, x, 0)), rel_record_null);
205 }
206
207 free_assoc_table (headers);
208 rel_free_table (new_patches);
209 }
210
211
212 static t_uchar *
arch_merge_points_prefix(const t_uchar * from_archive,const t_uchar * from_spec)213 arch_merge_points_prefix (const t_uchar * from_archive,
214 const t_uchar * from_spec)
215 {
216 if (!from_archive)
217 return 0;
218 else if (arch_valid_package_name (from_spec, arch_no_archive, arch_req_patch_level, 0))
219 return arch_fully_qualify (from_archive, from_spec);
220 else
221 return str_alloc_cat_many (0, from_archive, "/", from_spec, "--", str_end);
222 }
223
224
225
226
227
228
229 /* tag: Tom Lord Tue May 27 18:04:17 2003 (merge-points.c)
230 */
231