]>
Commit | Line | Data |
---|---|---|
c0cc6912 SC |
1 | /* arsup.c - Archive support for MRI compatibility */ |
2 | ||
3 | /* Copyright (C) 1992 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GNU Binutils. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | ||
21 | ||
22 | /* Contributed by Steve Chamberlain | |
23 | [email protected] | |
24 | ||
25 | This file looks after requests from arparse.y, to provide the MRI | |
26 | style librarian command syntax + 1 word LIST | |
27 | ||
28 | */ | |
29 | ||
30 | #include "bfd.h" | |
31 | #include "arsup.h" | |
32 | #include <sysdep.h> | |
33 | #include "bucomm.h" | |
34 | extern bfd *inarch; | |
35 | extern int verbose; | |
36 | ||
37 | ||
38 | ||
39 | void | |
40 | DEFUN(map_over_list,(function, list), | |
41 | void (*function) () AND | |
42 | struct list *list) | |
43 | ||
44 | { | |
45 | bfd *head; | |
46 | ||
47 | if (list == 0) { | |
48 | for (head = inarch->next; head; head = head->next){ | |
49 | function(head); | |
50 | } | |
51 | } | |
52 | else { | |
53 | /* | |
54 | This may appear to be a baroque way of accomplishing what we want. | |
55 | however we have to iterate over the filenames in order to notice where | |
56 | a filename is requested but does not exist in the archive. Ditto | |
57 | mapping over each file each time -- we want to hack multiple | |
58 | references. | |
59 | */ | |
60 | struct list *ptr = list; | |
61 | ||
62 | for (ptr = list; ptr; ptr=ptr->next) | |
63 | { | |
64 | boolean found = false; | |
65 | bfd *prev = inarch; | |
66 | for (head = inarch->next; head; head = head->next) | |
67 | { | |
68 | if ((head->filename != NULL) && | |
69 | (!strcmp(ptr->name, head->filename))) | |
70 | { | |
71 | found = true; | |
72 | function(head, prev); | |
73 | ||
74 | } | |
75 | prev = head; | |
76 | } | |
77 | if (!found) | |
78 | fprintf(stderr, "No entry %s in archive.\n", ptr->name); | |
79 | } | |
80 | } | |
81 | } | |
82 | ||
83 | ||
84 | FILE *outfile; | |
85 | void | |
86 | DEFUN(ar_directory_doer,(abfd), | |
87 | bfd *abfd) | |
88 | { | |
89 | print_arelt_descr(outfile, abfd, verbose); | |
90 | } | |
91 | ||
92 | void | |
93 | DEFUN(ar_directory,(ar_name, list, output), | |
94 | char *ar_name AND | |
95 | struct list *list AND | |
96 | char *output) | |
97 | { | |
98 | open_inarch(ar_name); | |
99 | if (output) { | |
100 | outfile = fopen(output,"w"); | |
101 | if (outfile == 0) { | |
102 | outfile =stdout; | |
103 | fprintf(stderr,"Can't open file %s\n", output); | |
104 | output = 0; | |
105 | } | |
106 | } | |
107 | else | |
108 | outfile = stdout; | |
109 | ||
110 | map_over_list(ar_directory_doer, list); | |
111 | bfd_close(inarch); | |
112 | if (output) | |
113 | fclose(outfile); | |
114 | } | |
115 | ||
116 | void | |
117 | DEFUN_VOID(prompt) | |
118 | { | |
119 | extern int interactive; | |
120 | if (interactive) | |
121 | { | |
122 | printf("AR >"); | |
123 | fflush(stdout); | |
124 | } | |
125 | } | |
126 | ||
127 | void | |
128 | DEFUN_VOID(maybequit) | |
129 | { | |
130 | if (!interactive) | |
131 | exit(9); | |
132 | } | |
133 | ||
134 | ||
135 | bfd *obfd; | |
136 | char *real_name ; | |
137 | void | |
138 | DEFUN(ar_open,(name, t), | |
139 | char *name AND | |
140 | int t) | |
141 | ||
142 | { | |
143 | char *tname = malloc(strlen(name)+10); | |
144 | real_name = name; | |
145 | sprintf(tname, "%s-tmp", name); | |
146 | obfd = bfd_openw(tname, NULL); | |
147 | ||
148 | if (!obfd) { | |
149 | fprintf(stderr,"%s: Can't open output archive %s\n", program_name, | |
150 | tname); | |
151 | ||
152 | maybequit(); | |
153 | } | |
154 | else { | |
155 | if (!t) { | |
156 | bfd **ptr; | |
157 | bfd *element; | |
158 | bfd *ibfd; | |
159 | ibfd = bfd_openr(name, NULL); | |
160 | if (bfd_check_format(ibfd, bfd_archive) != true) { | |
161 | fprintf(stderr,"%s: file %s is not an archive\n", program_name, | |
162 | name); | |
163 | maybequit(); | |
164 | return; | |
165 | } | |
166 | ptr = &(obfd->archive_head); | |
167 | element = bfd_openr_next_archived_file(ibfd, NULL); | |
168 | ||
169 | while (element) { | |
170 | *ptr = element; | |
171 | ptr = &element->next; | |
172 | element = bfd_openr_next_archived_file(ibfd, element); | |
173 | } | |
174 | } | |
175 | ||
176 | bfd_set_format(obfd, bfd_archive); | |
177 | ||
178 | obfd->has_armap = 1; | |
179 | } | |
180 | } | |
181 | ||
182 | ||
183 | void | |
184 | DEFUN(ar_addlib_doer, (abfd, prev), | |
185 | bfd *abfd AND | |
186 | bfd *prev) | |
187 | { | |
188 | /* Add this module to the output bfd */ | |
189 | ||
190 | prev->next = abfd->next; | |
191 | abfd->next = obfd->archive_head; | |
192 | obfd->archive_head = abfd; | |
193 | } | |
194 | ||
195 | void | |
196 | DEFUN(ar_addlib, (name, list), | |
197 | char *name AND | |
198 | struct list *list) | |
199 | { | |
200 | if (!obfd) { | |
201 | fprintf(stderr, "%s: no output archive specified yet\n", program_name); | |
202 | maybequit(); | |
203 | } | |
204 | else { | |
205 | if (open_inarch(name) ) { | |
206 | map_over_list(ar_addlib_doer, list); | |
207 | } | |
208 | /* Don't close the bfd, since it will make the elements disasppear */ | |
209 | } | |
210 | } | |
211 | ||
212 | ||
213 | ||
214 | void | |
215 | DEFUN(ar_addmod, (list), | |
216 | struct list *list) | |
217 | { | |
218 | if (!obfd) { | |
219 | fprintf(stderr, "%s: no open output archive\n", program_name); | |
220 | maybequit(); | |
221 | } | |
222 | else | |
223 | { | |
224 | while (list) { | |
225 | bfd *abfd = bfd_openr(list->name, NULL); | |
226 | if (!abfd) { | |
227 | fprintf(stderr,"%s: can't open file %s\n", program_name, | |
228 | list->name); | |
229 | maybequit(); | |
230 | } | |
231 | else { | |
232 | abfd->next = obfd->archive_head; | |
233 | obfd->archive_head = abfd; | |
234 | } | |
235 | list = list->next; | |
236 | } | |
237 | } | |
238 | } | |
239 | ||
240 | ||
241 | ||
242 | void | |
243 | DEFUN_VOID(ar_clear) | |
244 | { | |
245 | if (obfd) | |
246 | obfd->archive_head = 0; | |
247 | } | |
248 | ||
249 | void | |
250 | DEFUN(ar_delete, (list), | |
251 | struct list *list) | |
252 | { | |
253 | if (!obfd) { | |
254 | fprintf(stderr, "%s: no open output archive\n", program_name); | |
255 | maybequit(); | |
256 | } | |
257 | else | |
258 | { | |
259 | while (list) { | |
260 | /* Find this name in the archive */ | |
261 | bfd *member = obfd->archive_head; | |
262 | bfd **prev = &(obfd->archive_head); | |
263 | int found = 0; | |
264 | while (member) { | |
265 | if (strcmp(member->filename, list->name) == 0) { | |
266 | *prev = member->next; | |
267 | found = 1; | |
268 | } | |
269 | else { | |
270 | prev = &(member->next); | |
271 | } | |
272 | member = member->next; | |
273 | } | |
274 | if (!found) { | |
275 | fprintf(stderr,"%s: can't find module file %s\n", program_name, | |
276 | list->name); | |
277 | maybequit(); | |
278 | } | |
279 | list = list->next; | |
280 | } | |
281 | } | |
282 | } | |
283 | ||
284 | ||
285 | void | |
286 | DEFUN_VOID(ar_save) | |
287 | { | |
288 | ||
289 | if (!obfd) { | |
290 | fprintf(stderr, "%s: no open output archive\n", program_name); | |
291 | maybequit(); | |
292 | } | |
293 | else { | |
294 | bfd_close(obfd); | |
295 | unlink(real_name); | |
296 | link(obfd->filename, real_name); | |
297 | unlink(obfd->filename); | |
298 | obfd = 0; | |
299 | } | |
300 | } | |
301 | ||
302 | ||
303 | ||
304 | void | |
305 | DEFUN(ar_replace, (list), | |
306 | struct list *list) | |
307 | { | |
308 | if (!obfd) { | |
309 | fprintf(stderr, "%s: no open output archive\n", program_name); | |
310 | maybequit(); | |
311 | } | |
312 | else | |
313 | { | |
314 | while (list) { | |
315 | /* Find this name in the archive */ | |
316 | bfd *member = obfd->archive_head; | |
317 | bfd **prev = &(obfd->archive_head); | |
318 | int found = 0; | |
319 | while (member) | |
320 | { | |
321 | if (strcmp(member->filename, list->name) == 0) | |
322 | { | |
323 | /* Found the one to replace */ | |
324 | bfd *abfd = bfd_openr(list->name, 0); | |
325 | if (!abfd) | |
326 | { | |
327 | fprintf(stderr, "%s: can't open file %s\n", program_name, list->name); | |
328 | maybequit(); | |
329 | } | |
330 | else { | |
331 | *prev = abfd; | |
332 | abfd->next = member->next; | |
333 | found = 1; | |
334 | } | |
335 | } | |
336 | else { | |
337 | prev = &(member->next); | |
338 | } | |
339 | member = member->next; | |
340 | } | |
341 | if (!found) { | |
342 | bfd *abfd = bfd_openr(list->name, 0); | |
343 | fprintf(stderr,"%s: can't find module file %s\n", program_name, | |
344 | list->name); | |
345 | if (!abfd) | |
346 | { | |
347 | fprintf(stderr, "%s: can't open file %s\n", program_name, list->name); | |
348 | maybequit(); | |
349 | } | |
350 | else | |
351 | { | |
352 | *prev = abfd; | |
353 | } | |
354 | } | |
355 | ||
356 | list = list->next; | |
357 | } | |
358 | } | |
359 | } | |
360 | ||
361 | /* And I added this one */ | |
362 | void | |
363 | DEFUN_VOID(ar_list) | |
364 | { | |
365 | if (!obfd) | |
366 | { | |
367 | fprintf(stderr, "%s: no open output archive\n", program_name); | |
368 | maybequit(); | |
369 | } | |
370 | else { | |
371 | bfd *abfd; | |
372 | outfile = stdout; | |
373 | verbose =1 ; | |
374 | printf("Current open archive is %s\n", obfd->filename); | |
375 | for (abfd = obfd->archive_head; | |
376 | abfd != (bfd *)NULL; | |
377 | abfd = abfd->next) | |
378 | { | |
379 | ar_directory_doer(abfd); | |
380 | } | |
381 | } | |
382 | } | |
b7311408 SC |
383 | |
384 | ||
385 | void | |
386 | DEFUN(ar_extract,(list), | |
387 | struct list *list) | |
388 | { | |
389 | if (!obfd) | |
390 | { | |
391 | ||
392 | fprintf(stderr, "%s: no open archive\n", program_name); | |
393 | maybequit(); | |
394 | } | |
395 | else | |
396 | { | |
397 | while (list) { | |
398 | /* Find this name in the archive */ | |
399 | bfd *member = obfd->archive_head; | |
400 | int found = 0; | |
401 | while (member && !found) | |
402 | { | |
403 | if (strcmp(member->filename, list->name) == 0) | |
404 | { | |
405 | extract_file(member); | |
406 | found = 1; | |
407 | } | |
408 | ||
409 | member = member->next; | |
410 | } | |
411 | if (!found) { | |
412 | bfd *abfd = bfd_openr(list->name, 0); | |
413 | fprintf(stderr,"%s: can't find module file %s\n", program_name, | |
414 | list->name); | |
415 | ||
416 | } | |
417 | list = list->next; | |
418 | } | |
419 | } | |
420 | } |