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