1 /* archive-setup.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/arrays/ar.h"
13 #include "hackerlab/char/str.h"
14 #include "hackerlab/vu/safe.h"
15 #include "tla/libawk/associative.h"
16 #include "tla/libarch/chatter.h"
17 #include "tla/libarch/namespace.h"
18 #include "tla/libarch/archive.h"
19 #include "tla/libarch/tag.h"
20 #include "tla/libarch/archive-cache.h"
21 #include "tla/libarch/archive-setup.h"
22
23
24 /* __STDC__ prototypes for static functions */
25 static struct arch_archive * find_archive (struct arch_archive ** archs,
26 const t_uchar * name);
27
28
29
30 void
arch_setup_archive_simple(int chatter_fd,const t_uchar * archive_spec,const t_uchar * revision_spec)31 arch_setup_archive_simple (int chatter_fd,
32 const t_uchar * archive_spec,
33 const t_uchar * revision_spec)
34 {
35 rel_table wants = rel_table_nil;
36
37 rel_add_records (&wants, rel_make_record_2_taking (rel_make_field_str (archive_spec), rel_make_field_str (revision_spec)), rel_record_null);
38 arch_setup_archive (chatter_fd, wants, arch_archive_setup_no_tags, 0);
39
40 rel_free_table (wants);
41 }
42
43 void
arch_setup_archive_simple_ext(int chatter_fd,struct arch_archive * arch,const t_uchar * revision_spec)44 arch_setup_archive_simple_ext (int chatter_fd,
45 struct arch_archive * arch,
46 const t_uchar * revision_spec)
47 {
48 rel_table wants = rel_table_nil;
49
50 rel_add_records (&wants, rel_make_record_2_taking (rel_make_field_str (arch->name), rel_make_field_str (revision_spec)), rel_record_null);
51 arch_setup_archive_ext (chatter_fd, wants, arch_archive_setup_no_tags, 0, arch);
52
53 rel_free_table (wants);
54 }
55
56 void
arch_setup_archive(int chatter_fd,rel_table wants,enum arch_archive_setup_tag_op tag_op,int archive_cache)57 arch_setup_archive (int chatter_fd, rel_table wants,
58 enum arch_archive_setup_tag_op tag_op,
59 int archive_cache)
60 {
61 arch_setup_archive_ext (chatter_fd, wants, tag_op, archive_cache, NULL);
62 }
63
64 static void
arch_archive_populate_fqcategory_exists(struct arch_archive * arch,assoc_table * fqcategory_exists)65 arch_archive_populate_fqcategory_exists (struct arch_archive * arch, assoc_table * fqcategory_exists)
66 {
67 int c;
68 rel_table categories = arch_archive_categories (arch);
69
70 for (c = 0; c < rel_n_records (categories); ++c)
71 {
72 t_uchar * cat = 0;
73
74 cat = arch_fully_qualify (arch->name, rel_peek_str (categories, c, 0));
75 assoc_set_taking (fqcategory_exists, rel_make_field_str (cat), rel_make_field_str ("yes"));
76
77 lim_free (0, cat);
78 }
79
80 rel_free_table (categories);
81 }
82
83 void
arch_setup_archive_ext(int chatter_fd,rel_table wants,enum arch_archive_setup_tag_op tag_op,int archive_cache,struct arch_archive * initial_arch)84 arch_setup_archive_ext (int chatter_fd, rel_table wants,
85 enum arch_archive_setup_tag_op tag_op,
86 int archive_cache,
87 struct arch_archive * initial_arch)
88 {
89 t_uchar * errstr = 0;
90 struct arch_archive ** archs = 0;
91 assoc_table fqcategories_checked = 0;
92 assoc_table fqbranches_checked = 0;
93 assoc_table fqcategory_exists = 0;
94 assoc_table fqbranch_exists = 0;
95 assoc_table fqversion_exists = 0;
96 int x;
97
98 if (initial_arch)
99 *(struct arch_archive **)ar_push ((void **)&archs, 0, sizeof (initial_arch)) = initial_arch;
100
101 for (x = 0; x < rel_n_records (wants); ++x)
102 {
103 const t_uchar * archive;
104 struct arch_archive * arch = 0;
105 const t_uchar * spec;
106 t_uchar * category = 0;
107 t_uchar * fqcategory = 0;
108
109 archive = rel_peek_str (wants, x, 0);
110
111 arch = find_archive (archs, archive);
112
113 if (!arch)
114 {
115 arch = arch_archive_connect (archive, 0);
116 *(struct arch_archive **)ar_push ((void **)&archs, 0, sizeof (arch)) = arch;
117
118 arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists);
119 }
120
121 if (!fqcategory_exists)
122 arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists);
123
124 spec = rel_peek_str (wants, x, 1);
125
126 category = arch_parse_package_name (arch_ret_category, 0, spec);
127 fqcategory = arch_fully_qualify (archive, category);
128
129 if ((arch->type != arch_archive_baz) && !assoc_get_str_taking (fqcategory_exists, rel_make_field_str (fqcategory)))
130 {
131 arch_chatter (chatter_fd, "* creating category %s/%s\n", archive, category);
132 if (arch_make_category (&errstr, arch, category))
133 {
134 safe_printfmt (2, "archive-setup: error making category %s/%s (%s)\n", archive, category, errstr);
135 exit (1);
136 }
137 assoc_set_taking (&fqcategory_exists, rel_make_field_str (fqcategory), rel_make_field_str ("yes"));
138 }
139
140 if (str_cmp (spec, category))
141 {
142 if (arch_valid_package_name (spec, arch_no_archive, arch_req_package, 1))
143 {
144 t_uchar * branch = 0;
145 t_uchar * fqbranch = 0;
146
147 branch = arch_parse_package_name (arch_ret_package, 0, spec);
148 fqbranch = arch_fully_qualify (archive, branch);
149
150 if (!assoc_get_str_taking (fqcategories_checked, rel_make_field_str (fqcategory)))
151 {
152 rel_table branches = rel_table_nil;
153 int b;
154
155 branches = arch_archive_branches (arch, category);
156 for (b = 0; b < rel_n_records (branches); ++b)
157 {
158 t_uchar * bran = 0;
159
160 bran = arch_fully_qualify (archive, rel_peek_str (branches, b, 0));
161 assoc_set_taking (&fqbranch_exists, rel_make_field_str (bran), rel_make_field_str ("yes"));
162
163 lim_free (0, bran);
164 }
165
166 rel_free_table (branches);
167 }
168
169 if ((arch->type != arch_archive_baz) && !assoc_get_str_taking (fqbranch_exists, rel_make_field_str (fqbranch)))
170 {
171 arch_chatter (chatter_fd, "* creating branch %s/%s\n", archive, branch);
172 if (arch_make_branch (&errstr, arch, branch))
173 {
174 safe_printfmt (2, "archive-setup: error making branch %s/%s (%s)\n", archive, branch, errstr);
175 exit (1);
176 }
177 assoc_set_taking (&fqbranch_exists, rel_make_field_str (fqbranch), rel_make_field_str ("yes"));
178 }
179
180 if (arch_valid_package_name (spec, arch_no_archive, arch_req_version, 0))
181 {
182 t_uchar * version = 0;
183 t_uchar * fqversion = 0;
184
185 version = arch_parse_package_name (arch_ret_package_version, 0, spec);
186 fqversion = arch_fully_qualify (archive, version);
187
188 if (!assoc_get_str_taking (fqbranches_checked, rel_make_field_str (fqbranch)))
189 {
190 rel_table versions = rel_table_nil;
191 int v;
192
193 versions = arch_archive_versions (arch, branch);
194 for (v = 0; v < rel_n_records (versions); ++v)
195 {
196 t_uchar * vers = 0;
197 vers = arch_fully_qualify (archive, rel_peek_str (versions, v, 0));
198 assoc_set_taking (&fqversion_exists, rel_make_field_str (vers), rel_make_field_str ("yes"));
199 lim_free (0, vers);
200 }
201
202 rel_free_table (versions);
203 }
204
205 if (!assoc_get_str_taking (fqversion_exists, rel_make_field_str (fqversion)))
206 {
207 arch_chatter (chatter_fd, "* creating version %s/%s\n", archive, version);
208 if (arch_make_version (&errstr, arch, version))
209 {
210 safe_printfmt (2, "archive-setup: error making version %s/%s (%s)\n", archive, version, errstr);
211 exit (1);
212 }
213 assoc_set_taking (&fqversion_exists, rel_make_field_str (fqversion), rel_make_field_str ("yes"));
214 }
215
216 if (tag_op != arch_archive_setup_no_tags)
217 {
218 rel_table has_revisions = rel_table_nil;
219
220 const t_uchar * tag_from_archive;
221 const t_uchar * tag_from_rev_spec;
222
223 struct arch_archive * from_arch = 0;
224 t_uchar * tag_from_version = 0;
225 rel_table from_has_revisions = rel_table_nil;
226
227 arch_chatter (chatter_fd, "* creating tag in %s/%s\n", archive, version);
228 has_revisions = arch_archive_revisions (arch, version, 0);
229
230 tag_from_archive = rel_peek_str (wants, x, 2);
231 tag_from_rev_spec = rel_peek_str (wants, x, 3);
232
233 from_arch = find_archive (archs, tag_from_archive);
234 if (!from_arch)
235 {
236 from_arch = arch_archive_connect (tag_from_archive, 0);
237 *(struct arch_archive **)ar_push ((void **)&archs, 0, sizeof (arch)) = from_arch;
238 }
239
240 tag_from_version = arch_parse_package_name (arch_ret_package_version, 0, tag_from_rev_spec);
241 from_has_revisions = arch_archive_revisions (from_arch, tag_from_version, 0);
242
243 switch (tag_op)
244 {
245 default:
246 {
247 panic ("archive-setup.c internal error");
248 break;
249 }
250 case arch_archive_setup_make_base0_tag:
251 {
252 if (rel_n_records (has_revisions))
253 arch_chatter (chatter_fd, " ...skipping, base-0 already exists");
254 else
255 {
256 t_uchar * tag_revision = 0;
257 t_uchar * tag_from_revision = 0;
258
259 tag_revision = str_alloc_cat (0, version, "--base-0");
260
261 if (arch_valid_package_name (tag_from_rev_spec, 0, arch_req_patch_level, 0))
262 tag_from_revision = arch_parse_package_name (arch_ret_non_archive, 0, tag_from_rev_spec);
263 else if (rel_n_records (from_has_revisions))
264 tag_from_revision = str_alloc_cat_many (0, tag_from_version, "--", rel_peek_str (from_has_revisions, rel_n_records (from_has_revisions) - 1, 0), str_end);
265
266 if (tag_from_revision)
267 {
268 arch_tag (chatter_fd, arch, tag_revision, from_arch, tag_from_revision, 0);
269
270 if (archive_cache)
271 {
272 arch_chatter (chatter_fd, "* archive caching %s/%s\n", archive, tag_revision);
273 arch_archive_cache (chatter_fd, arch, archive, tag_revision, 0);
274 }
275 }
276
277 lim_free (0, tag_from_revision);
278 lim_free (0, tag_revision);
279 }
280
281 break;
282 }
283 }
284
285 rel_free_table (has_revisions);
286 lim_free (0, tag_from_version);
287 rel_free_table (from_has_revisions);
288 }
289
290 lim_free (0, version);
291 lim_free (0, fqversion);
292 }
293
294 lim_free (0, branch);
295 lim_free (0, fqbranch);
296 }
297 }
298 lim_free (0, category);
299 lim_free (0, fqcategory);
300 }
301
302 for (x = 0; x < ar_size ((void *)archs, 0, sizeof (*archs)); ++x)
303 if (archs[x] != initial_arch)
304 arch_archive_close (archs[x]);
305
306 ar_free ((void **)&archs, 0);
307 free_assoc_table (fqcategories_checked);
308 free_assoc_table (fqbranches_checked);
309 free_assoc_table (fqcategory_exists);
310 free_assoc_table (fqbranch_exists);
311 free_assoc_table (fqversion_exists);
312 }
313
314
315 static struct arch_archive *
find_archive(struct arch_archive ** archs,const t_uchar * name)316 find_archive (struct arch_archive ** archs,
317 const t_uchar * name)
318 {
319 int x;
320
321 for (x = 0; x < ar_size ((void *)archs, 0, sizeof (*archs)); ++x)
322 if (!str_cmp (name, archs[x]->name))
323 return archs[x];
324
325 return 0;
326 }
327
328
329
330 /* tag: Tom Lord Wed Jun 11 11:58:43 2003 (archive-setup.c)
331 */
332