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