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