]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/arsup.c
bfd/
[thirdparty/binutils-gdb.git] / binutils / arsup.c
CommitLineData
252b5132 1/* arsup.c - Archive support for MRI compatibility
aef6203b 2 Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
3db64b00 3 2004, 2007 Free Software Foundation, Inc.
252b5132 4
3a1a2036 5 This file is part of GNU Binutils.
252b5132 6
3a1a2036
NC
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.
252b5132 11
3a1a2036
NC
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.
252b5132 16
3a1a2036
NC
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
b43b5d5f 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132
RH
20
21
22/* Contributed by Steve Chamberlain
3a1a2036 23 sac@cygnus.com
252b5132 24
3a1a2036
NC
25 This file looks after requests from arparse.y, to provide the MRI
26 style librarian command syntax + 1 word LIST. */
252b5132 27
3db64b00 28#include "sysdep.h"
252b5132 29#include "bfd.h"
252b5132 30#include "libiberty.h"
5af11cab 31#include "filenames.h"
3db64b00
AM
32#include "bucomm.h"
33#include "arsup.h"
252b5132
RH
34
35static void map_over_list
2da42df6
AJ
36 (bfd *, void (*function) (bfd *, bfd *), struct list *);
37static void ar_directory_doer (bfd *, bfd *);
38static void ar_addlib_doer (bfd *, bfd *);
252b5132
RH
39
40extern int verbose;
41
85b1c36d
BE
42static bfd *obfd;
43static char *real_name;
44static FILE *outfile;
45
252b5132 46static void
2da42df6 47map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list)
252b5132
RH
48{
49 bfd *head;
50
51 if (list == NULL)
52 {
53 bfd *next;
54
55 head = arch->next;
56 while (head != NULL)
57 {
58 next = head->next;
59 function (head, (bfd *) NULL);
60 head = next;
61 }
62 }
63 else
64 {
65 struct list *ptr;
66
67 /* This may appear to be a baroque way of accomplishing what we
68 want. however we have to iterate over the filenames in order
69 to notice where a filename is requested but does not exist in
70 the archive. Ditto mapping over each file each time -- we
71 want to hack multiple references. */
72 for (ptr = list; ptr; ptr = ptr->next)
73 {
b34976b6 74 bfd_boolean found = FALSE;
252b5132
RH
75 bfd *prev = arch;
76
f462a9ea 77 for (head = arch->next; head; head = head->next)
252b5132
RH
78 {
79 if (head->filename != NULL
5af11cab 80 && FILENAME_CMP (ptr->name, head->filename) == 0)
252b5132 81 {
b34976b6 82 found = TRUE;
252b5132
RH
83 function (head, prev);
84 }
85 prev = head;
86 }
87 if (! found)
88 fprintf (stderr, _("No entry %s in archive.\n"), ptr->name);
89 }
90 }
91}
92
93
252b5132 94
252b5132 95static void
2da42df6 96ar_directory_doer (bfd *abfd, bfd *ignore ATTRIBUTE_UNUSED)
252b5132 97{
3a1a2036 98 print_arelt_descr(outfile, abfd, verbose);
252b5132
RH
99}
100
101void
2da42df6 102ar_directory (char *ar_name, struct list *list, char *output)
252b5132
RH
103{
104 bfd *arch;
105
106 arch = open_inarch (ar_name, (char *) NULL);
107 if (output)
108 {
109 outfile = fopen(output,"w");
110 if (outfile == 0)
111 {
112 outfile = stdout;
113 fprintf (stderr,_("Can't open file %s\n"), output);
114 output = 0;
115 }
116 }
f462a9ea 117 else
252b5132
RH
118 outfile = stdout;
119
120 map_over_list (arch, ar_directory_doer, list);
121
122 bfd_close (arch);
123
124 if (output)
125 fclose (outfile);
126}
127
128void
2da42df6 129prompt (void)
252b5132
RH
130{
131 extern int interactive;
3a1a2036 132
f462a9ea 133 if (interactive)
3a1a2036
NC
134 {
135 printf ("AR >");
136 fflush (stdout);
137 }
252b5132
RH
138}
139
140void
2da42df6 141maybequit (void)
252b5132 142{
f462a9ea 143 if (! interactive)
252b5132
RH
144 xexit (9);
145}
146
147
3a1a2036 148void
2da42df6 149ar_open (char *name, int t)
252b5132
RH
150{
151 char *tname = (char *) xmalloc (strlen (name) + 10);
5e9520c8 152 const char *bname = lbasename (name);
252b5132 153 real_name = name;
3a1a2036 154
5af11cab
AM
155 /* Prepend tmp- to the beginning, to avoid file-name clashes after
156 truncation on filesystems with limited namespaces (DOS). */
3a1a2036
NC
157 sprintf (tname, "%.*stmp-%s", (int) (bname - name), name, bname);
158 obfd = bfd_openw (tname, NULL);
159
160 if (!obfd)
161 {
162 fprintf (stderr,
163 _("%s: Can't open output archive %s\n"),
164 program_name, tname);
165
166 maybequit ();
252b5132 167 }
3a1a2036
NC
168 else
169 {
170 if (!t)
171 {
172 bfd **ptr;
173 bfd *element;
174 bfd *ibfd;
252b5132 175
3a1a2036 176 ibfd = bfd_openr (name, NULL);
252b5132 177
3a1a2036
NC
178 if (!ibfd)
179 {
180 fprintf (stderr,_("%s: Can't open input archive %s\n"),
181 program_name, name);
182 maybequit ();
183 return;
184 }
185
b34976b6 186 if (!bfd_check_format(ibfd, bfd_archive))
3a1a2036
NC
187 {
188 fprintf (stderr,
189 _("%s: file %s is not an archive\n"),
190 program_name, name);
191 maybequit ();
192 return;
193 }
194
195 ptr = &(obfd->archive_head);
196 element = bfd_openr_next_archived_file (ibfd, NULL);
197
198 while (element)
199 {
200 *ptr = element;
201 ptr = &element->next;
202 element = bfd_openr_next_archived_file (ibfd, element);
203 }
204 }
205
206 bfd_set_format (obfd, bfd_archive);
252b5132 207
3a1a2036
NC
208 obfd->has_armap = 1;
209 }
210}
252b5132
RH
211
212static void
2da42df6 213ar_addlib_doer (bfd *abfd, bfd *prev)
252b5132 214{
3a1a2036 215 /* Add this module to the output bfd. */
252b5132
RH
216 if (prev != NULL)
217 prev->next = abfd->next;
3a1a2036 218
252b5132
RH
219 abfd->next = obfd->archive_head;
220 obfd->archive_head = abfd;
221}
222
223void
2da42df6 224ar_addlib (char *name, struct list *list)
252b5132
RH
225{
226 if (obfd == NULL)
227 {
228 fprintf (stderr, _("%s: no output archive specified yet\n"), program_name);
229 maybequit ();
230 }
231 else
232 {
233 bfd *arch;
234
235 arch = open_inarch (name, (char *) NULL);
236 if (arch != NULL)
237 map_over_list (arch, ar_addlib_doer, list);
238
50c2245b 239 /* Don't close the bfd, since it will make the elements disappear. */
252b5132
RH
240 }
241}
242
243void
2da42df6 244ar_addmod (struct list *list)
252b5132 245{
3a1a2036
NC
246 if (!obfd)
247 {
248 fprintf (stderr, _("%s: no open output archive\n"), program_name);
249 maybequit ();
250 }
f462a9ea 251 else
3a1a2036
NC
252 {
253 while (list)
254 {
255 bfd *abfd = bfd_openr (list->name, NULL);
256
257 if (!abfd)
258 {
259 fprintf (stderr, _("%s: can't open file %s\n"),
260 program_name, list->name);
261 maybequit ();
262 }
263 else
264 {
265 abfd->next = obfd->archive_head;
266 obfd->archive_head = abfd;
267 }
268 list = list->next;
269 }
252b5132 270 }
252b5132
RH
271}
272
273
252b5132 274void
2da42df6 275ar_clear (void)
252b5132 276{
3a1a2036
NC
277 if (obfd)
278 obfd->archive_head = 0;
252b5132
RH
279}
280
281void
2da42df6 282ar_delete (struct list *list)
252b5132 283{
3a1a2036
NC
284 if (!obfd)
285 {
286 fprintf (stderr, _("%s: no open output archive\n"), program_name);
287 maybequit ();
288 }
f462a9ea 289 else
3a1a2036
NC
290 {
291 while (list)
292 {
293 /* Find this name in the archive. */
294 bfd *member = obfd->archive_head;
295 bfd **prev = &(obfd->archive_head);
296 int found = 0;
297
298 while (member)
299 {
300 if (FILENAME_CMP(member->filename, list->name) == 0)
301 {
302 *prev = member->next;
303 found = 1;
304 }
305 else
306 prev = &(member->next);
307
308 member = member->next;
309 }
310
311 if (!found)
312 {
313 fprintf (stderr, _("%s: can't find module file %s\n"),
314 program_name, list->name);
315 maybequit ();
316 }
317
318 list = list->next;
252b5132 319 }
252b5132 320 }
252b5132
RH
321}
322
252b5132 323void
2da42df6 324ar_save (void)
252b5132 325{
3a1a2036
NC
326 if (!obfd)
327 {
328 fprintf (stderr, _("%s: no open output archive\n"), program_name);
329 maybequit ();
330 }
331 else
332 {
333 char *ofilename = xstrdup (bfd_get_filename (obfd));
252b5132 334
3a1a2036 335 bfd_close (obfd);
252b5132 336
1ba93119 337 smart_rename (ofilename, real_name, 0);
3a1a2036
NC
338 obfd = 0;
339 free (ofilename);
340 }
341}
252b5132
RH
342
343void
2da42df6 344ar_replace (struct list *list)
252b5132 345{
3a1a2036
NC
346 if (!obfd)
347 {
348 fprintf (stderr, _("%s: no open output archive\n"), program_name);
349 maybequit ();
350 }
f462a9ea 351 else
3a1a2036
NC
352 {
353 while (list)
252b5132 354 {
3a1a2036
NC
355 /* Find this name in the archive. */
356 bfd *member = obfd->archive_head;
357 bfd **prev = &(obfd->archive_head);
358 int found = 0;
359
360 while (member)
361 {
362 if (FILENAME_CMP (member->filename, list->name) == 0)
363 {
364 /* Found the one to replace. */
365 bfd *abfd = bfd_openr (list->name, 0);
366
367 if (!abfd)
368 {
369 fprintf (stderr, _("%s: can't open file %s\n"),
370 program_name, list->name);
371 maybequit ();
372 }
373 else
374 {
375 *prev = abfd;
376 abfd->next = member->next;
377 found = 1;
378 }
379 }
380 else
381 {
382 prev = &(member->next);
383 }
384 member = member->next;
385 }
386
387 if (!found)
388 {
389 bfd *abfd = bfd_openr (list->name, 0);
252b5132 390
3a1a2036
NC
391 fprintf (stderr,_("%s: can't find module file %s\n"),
392 program_name, list->name);
393 if (!abfd)
394 {
395 fprintf (stderr, _("%s: can't open file %s\n"),
396 program_name, list->name);
397 maybequit ();
398 }
399 else
400 *prev = abfd;
401 }
402
403 list = list->next;
404 }
252b5132 405 }
252b5132
RH
406}
407
3a1a2036 408/* And I added this one. */
252b5132 409void
2da42df6 410ar_list (void)
252b5132 411{
f462a9ea 412 if (!obfd)
252b5132 413 {
3a1a2036
NC
414 fprintf (stderr, _("%s: no open output archive\n"), program_name);
415 maybequit ();
252b5132 416 }
3a1a2036
NC
417 else
418 {
419 bfd *abfd;
420
421 outfile = stdout;
422 verbose =1 ;
423 printf (_("Current open archive is %s\n"), bfd_get_filename (obfd));
252b5132 424
3a1a2036
NC
425 for (abfd = obfd->archive_head;
426 abfd != (bfd *)NULL;
427 abfd = abfd->next)
428 ar_directory_doer (abfd, (bfd *) NULL);
429 }
430}
252b5132 431
f462a9ea 432void
2da42df6 433ar_end (void)
252b5132
RH
434{
435 if (obfd)
3a1a2036 436 {
c92c35e7 437 bfd_cache_close (obfd);
3a1a2036
NC
438 unlink (bfd_get_filename (obfd));
439 }
252b5132 440}
3a1a2036 441
252b5132 442void
2da42df6 443ar_extract (struct list *list)
252b5132 444{
f462a9ea 445 if (!obfd)
3a1a2036
NC
446 {
447 fprintf (stderr, _("%s: no open archive\n"), program_name);
448 maybequit ();
449 }
f462a9ea 450 else
3a1a2036
NC
451 {
452 while (list)
252b5132 453 {
3a1a2036
NC
454 /* Find this name in the archive. */
455 bfd *member = obfd->archive_head;
456 int found = 0;
457
458 while (member && !found)
459 {
460 if (FILENAME_CMP (member->filename, list->name) == 0)
461 {
462 extract_file (member);
463 found = 1;
464 }
465
466 member = member->next;
467 }
468
469 if (!found)
470 {
471 bfd_openr (list->name, 0);
472 fprintf (stderr, _("%s: can't find module file %s\n"),
473 program_name, list->name);
474 }
475
476 list = list->next;
477 }
252b5132 478 }
252b5132 479}