merge from gcc
[binutils.git] / binutils / arsup.c
blobb3e967243aa72182c65455af646d04e89d0fe465
1 /* arsup.c - Archive support for MRI compatibility
2 Copyright 1992, 1994, 1995, 1996, 1997, 2000, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 /* Contributed by Steve Chamberlain
23 sac@cygnus.com
25 This file looks after requests from arparse.y, to provide the MRI
26 style librarian command syntax + 1 word LIST. */
28 #include "bfd.h"
29 #include "arsup.h"
30 #include "libiberty.h"
31 #include "bucomm.h"
32 #include "filenames.h"
34 static void map_over_list
35 PARAMS ((bfd *, void (*function) (bfd *, bfd *), struct list *));
36 static void ar_directory_doer PARAMS ((bfd *, bfd *));
37 static void ar_addlib_doer PARAMS ((bfd *, bfd *));
39 extern int verbose;
41 static void
42 map_over_list (arch, function, list)
43 bfd *arch;
44 void (*function) PARAMS ((bfd *, bfd *));
45 struct list *list;
47 bfd *head;
49 if (list == NULL)
51 bfd *next;
53 head = arch->next;
54 while (head != NULL)
56 next = head->next;
57 function (head, (bfd *) NULL);
58 head = next;
61 else
63 struct list *ptr;
65 /* This may appear to be a baroque way of accomplishing what we
66 want. however we have to iterate over the filenames in order
67 to notice where a filename is requested but does not exist in
68 the archive. Ditto mapping over each file each time -- we
69 want to hack multiple references. */
70 for (ptr = list; ptr; ptr = ptr->next)
72 bfd_boolean found = FALSE;
73 bfd *prev = arch;
75 for (head = arch->next; head; head = head->next)
77 if (head->filename != NULL
78 && FILENAME_CMP (ptr->name, head->filename) == 0)
80 found = TRUE;
81 function (head, prev);
83 prev = head;
85 if (! found)
86 fprintf (stderr, _("No entry %s in archive.\n"), ptr->name);
92 FILE *outfile;
94 static void
95 ar_directory_doer (abfd, ignore)
96 bfd *abfd;
97 bfd *ignore ATTRIBUTE_UNUSED;
99 print_arelt_descr(outfile, abfd, verbose);
102 void
103 ar_directory (ar_name, list, output)
104 char *ar_name;
105 struct list *list;
106 char *output;
108 bfd *arch;
110 arch = open_inarch (ar_name, (char *) NULL);
111 if (output)
113 outfile = fopen(output,"w");
114 if (outfile == 0)
116 outfile = stdout;
117 fprintf (stderr,_("Can't open file %s\n"), output);
118 output = 0;
121 else
122 outfile = stdout;
124 map_over_list (arch, ar_directory_doer, list);
126 bfd_close (arch);
128 if (output)
129 fclose (outfile);
132 void
133 DEFUN_VOID(prompt)
135 extern int interactive;
137 if (interactive)
139 printf ("AR >");
140 fflush (stdout);
144 void
145 maybequit ()
147 if (! interactive)
148 xexit (9);
152 bfd *obfd;
153 char *real_name;
155 void
156 ar_open (name, t)
157 char *name;
158 int t;
160 char *tname = (char *) xmalloc (strlen (name) + 10);
161 const char *bname = lbasename (name);
162 real_name = name;
164 /* Prepend tmp- to the beginning, to avoid file-name clashes after
165 truncation on filesystems with limited namespaces (DOS). */
166 sprintf (tname, "%.*stmp-%s", (int) (bname - name), name, bname);
167 obfd = bfd_openw (tname, NULL);
169 if (!obfd)
171 fprintf (stderr,
172 _("%s: Can't open output archive %s\n"),
173 program_name, tname);
175 maybequit ();
177 else
179 if (!t)
181 bfd **ptr;
182 bfd *element;
183 bfd *ibfd;
185 ibfd = bfd_openr (name, NULL);
187 if (!ibfd)
189 fprintf (stderr,_("%s: Can't open input archive %s\n"),
190 program_name, name);
191 maybequit ();
192 return;
195 if (!bfd_check_format(ibfd, bfd_archive))
197 fprintf (stderr,
198 _("%s: file %s is not an archive\n"),
199 program_name, name);
200 maybequit ();
201 return;
204 ptr = &(obfd->archive_head);
205 element = bfd_openr_next_archived_file (ibfd, NULL);
207 while (element)
209 *ptr = element;
210 ptr = &element->next;
211 element = bfd_openr_next_archived_file (ibfd, element);
215 bfd_set_format (obfd, bfd_archive);
217 obfd->has_armap = 1;
221 static void
222 ar_addlib_doer (abfd, prev)
223 bfd *abfd;
224 bfd *prev;
226 /* Add this module to the output bfd. */
227 if (prev != NULL)
228 prev->next = abfd->next;
230 abfd->next = obfd->archive_head;
231 obfd->archive_head = abfd;
234 void
235 ar_addlib (name, list)
236 char *name;
237 struct list *list;
239 if (obfd == NULL)
241 fprintf (stderr, _("%s: no output archive specified yet\n"), program_name);
242 maybequit ();
244 else
246 bfd *arch;
248 arch = open_inarch (name, (char *) NULL);
249 if (arch != NULL)
250 map_over_list (arch, ar_addlib_doer, list);
252 /* Don't close the bfd, since it will make the elements disasppear. */
256 void
257 ar_addmod (list)
258 struct list *list;
260 if (!obfd)
262 fprintf (stderr, _("%s: no open output archive\n"), program_name);
263 maybequit ();
265 else
267 while (list)
269 bfd *abfd = bfd_openr (list->name, NULL);
271 if (!abfd)
273 fprintf (stderr, _("%s: can't open file %s\n"),
274 program_name, list->name);
275 maybequit ();
277 else
279 abfd->next = obfd->archive_head;
280 obfd->archive_head = abfd;
282 list = list->next;
288 void
289 ar_clear ()
291 if (obfd)
292 obfd->archive_head = 0;
295 void
296 ar_delete (list)
297 struct list *list;
299 if (!obfd)
301 fprintf (stderr, _("%s: no open output archive\n"), program_name);
302 maybequit ();
304 else
306 while (list)
308 /* Find this name in the archive. */
309 bfd *member = obfd->archive_head;
310 bfd **prev = &(obfd->archive_head);
311 int found = 0;
313 while (member)
315 if (FILENAME_CMP(member->filename, list->name) == 0)
317 *prev = member->next;
318 found = 1;
320 else
321 prev = &(member->next);
323 member = member->next;
326 if (!found)
328 fprintf (stderr, _("%s: can't find module file %s\n"),
329 program_name, list->name);
330 maybequit ();
333 list = list->next;
338 void
339 ar_save ()
341 if (!obfd)
343 fprintf (stderr, _("%s: no open output archive\n"), program_name);
344 maybequit ();
346 else
348 char *ofilename = xstrdup (bfd_get_filename (obfd));
350 bfd_close (obfd);
352 rename (ofilename, real_name);
353 obfd = 0;
354 free (ofilename);
358 void
359 ar_replace (list)
360 struct list *list;
362 if (!obfd)
364 fprintf (stderr, _("%s: no open output archive\n"), program_name);
365 maybequit ();
367 else
369 while (list)
371 /* Find this name in the archive. */
372 bfd *member = obfd->archive_head;
373 bfd **prev = &(obfd->archive_head);
374 int found = 0;
376 while (member)
378 if (FILENAME_CMP (member->filename, list->name) == 0)
380 /* Found the one to replace. */
381 bfd *abfd = bfd_openr (list->name, 0);
383 if (!abfd)
385 fprintf (stderr, _("%s: can't open file %s\n"),
386 program_name, list->name);
387 maybequit ();
389 else
391 *prev = abfd;
392 abfd->next = member->next;
393 found = 1;
396 else
398 prev = &(member->next);
400 member = member->next;
403 if (!found)
405 bfd *abfd = bfd_openr (list->name, 0);
407 fprintf (stderr,_("%s: can't find module file %s\n"),
408 program_name, list->name);
409 if (!abfd)
411 fprintf (stderr, _("%s: can't open file %s\n"),
412 program_name, list->name);
413 maybequit ();
415 else
416 *prev = abfd;
419 list = list->next;
424 /* And I added this one. */
425 void
426 ar_list ()
428 if (!obfd)
430 fprintf (stderr, _("%s: no open output archive\n"), program_name);
431 maybequit ();
433 else
435 bfd *abfd;
437 outfile = stdout;
438 verbose =1 ;
439 printf (_("Current open archive is %s\n"), bfd_get_filename (obfd));
441 for (abfd = obfd->archive_head;
442 abfd != (bfd *)NULL;
443 abfd = abfd->next)
444 ar_directory_doer (abfd, (bfd *) NULL);
448 void
449 ar_end ()
451 if (obfd)
453 fclose ((FILE *)(obfd->iostream));
454 unlink (bfd_get_filename (obfd));
458 void
459 ar_extract (list)
460 struct list *list;
462 if (!obfd)
464 fprintf (stderr, _("%s: no open archive\n"), program_name);
465 maybequit ();
467 else
469 while (list)
471 /* Find this name in the archive. */
472 bfd *member = obfd->archive_head;
473 int found = 0;
475 while (member && !found)
477 if (FILENAME_CMP (member->filename, list->name) == 0)
479 extract_file (member);
480 found = 1;
483 member = member->next;
486 if (!found)
488 bfd_openr (list->name, 0);
489 fprintf (stderr, _("%s: can't find module file %s\n"),
490 program_name, list->name);
493 list = list->next;