diff options
author | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
commit | 252b5132c753830d5fd56823373aed85f2a0db63 (patch) | |
tree | 1af963bfd8d3e55167b81def4207f175eaff3a56 /binutils/arsup.c | |
download | gdb-252b5132c753830d5fd56823373aed85f2a0db63.zip gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.gz gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.bz2 |
19990502 sourceware importbinu_ss_19990502
Diffstat (limited to 'binutils/arsup.c')
-rw-r--r-- | binutils/arsup.c | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/binutils/arsup.c b/binutils/arsup.c new file mode 100644 index 0000000..38fd695 --- /dev/null +++ b/binutils/arsup.c @@ -0,0 +1,456 @@ +/* arsup.c - Archive support for MRI compatibility + Copyright (C) 1992, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +/* Contributed by Steve Chamberlain + sac@cygnus.com + +This file looks after requests from arparse.y, to provide the MRI +style librarian command syntax + 1 word LIST + +*/ + +#include "bfd.h" +#include "arsup.h" +#include "libiberty.h" +#include "bucomm.h" + +static void map_over_list + PARAMS ((bfd *, void (*function) (bfd *, bfd *), struct list *)); +static void ar_directory_doer PARAMS ((bfd *, bfd *)); +static void ar_addlib_doer PARAMS ((bfd *, bfd *)); + +extern int verbose; + +static void +map_over_list (arch, function, list) + bfd *arch; + void (*function) PARAMS ((bfd *, bfd *)); + struct list *list; +{ + bfd *head; + + if (list == NULL) + { + bfd *next; + + head = arch->next; + while (head != NULL) + { + next = head->next; + function (head, (bfd *) NULL); + head = next; + } + } + else + { + struct list *ptr; + + /* This may appear to be a baroque way of accomplishing what we + want. however we have to iterate over the filenames in order + to notice where a filename is requested but does not exist in + the archive. Ditto mapping over each file each time -- we + want to hack multiple references. */ + for (ptr = list; ptr; ptr = ptr->next) + { + boolean found = false; + bfd *prev = arch; + + for (head = arch->next; head; head = head->next) + { + if (head->filename != NULL + && strcmp (ptr->name, head->filename) == 0) + { + found = true; + function (head, prev); + } + prev = head; + } + if (! found) + fprintf (stderr, _("No entry %s in archive.\n"), ptr->name); + } + } +} + + +FILE *outfile; + +/*ARGSUSED*/ +static void +ar_directory_doer (abfd, ignore) + bfd *abfd; + bfd *ignore; +{ + print_arelt_descr(outfile, abfd, verbose); +} + +void +ar_directory (ar_name, list, output) + char *ar_name; + struct list *list; + char *output; +{ + bfd *arch; + + arch = open_inarch (ar_name, (char *) NULL); + if (output) + { + outfile = fopen(output,"w"); + if (outfile == 0) + { + outfile = stdout; + fprintf (stderr,_("Can't open file %s\n"), output); + output = 0; + } + } + else + outfile = stdout; + + map_over_list (arch, ar_directory_doer, list); + + bfd_close (arch); + + if (output) + fclose (outfile); +} + +void +DEFUN_VOID(prompt) +{ + extern int interactive; + if (interactive) + { + printf("AR >"); + fflush(stdout); + } +} + +void +maybequit () +{ + if (! interactive) + xexit (9); +} + + +bfd *obfd; +char *real_name ; +void +DEFUN(ar_open,(name, t), + char *name AND + int t) + +{ + char *tname = (char *) xmalloc (strlen (name) + 10); + real_name = name; + sprintf(tname, "%s-tmp", name); + obfd = bfd_openw(tname, NULL); + + if (!obfd) { + fprintf(stderr,_("%s: Can't open output archive %s\n"), program_name, + tname); + + maybequit(); + } + else { + if (!t) { + bfd **ptr; + bfd *element; + bfd *ibfd; + ibfd = bfd_openr(name, NULL); + if (!ibfd) { + fprintf(stderr,_("%s: Can't open input archive %s\n"), + program_name, name); + maybequit(); + return; + } + if (bfd_check_format(ibfd, bfd_archive) != true) { + fprintf(stderr,_("%s: file %s is not an archive\n"), program_name, + name); + maybequit(); + return; + } + ptr = &(obfd->archive_head); + element = bfd_openr_next_archived_file(ibfd, NULL); + + while (element) { + *ptr = element; + ptr = &element->next; + element = bfd_openr_next_archived_file(ibfd, element); + } + } + + bfd_set_format(obfd, bfd_archive); + + obfd->has_armap = 1; + } +} + + +static void +ar_addlib_doer (abfd, prev) + bfd *abfd; + bfd *prev; +{ + /* Add this module to the output bfd */ + if (prev != NULL) + prev->next = abfd->next; + abfd->next = obfd->archive_head; + obfd->archive_head = abfd; +} + +void +ar_addlib (name, list) + char *name; + struct list *list; +{ + if (obfd == NULL) + { + fprintf (stderr, _("%s: no output archive specified yet\n"), program_name); + maybequit (); + } + else + { + bfd *arch; + + arch = open_inarch (name, (char *) NULL); + if (arch != NULL) + map_over_list (arch, ar_addlib_doer, list); + + /* Don't close the bfd, since it will make the elements disasppear */ + } +} + +void +DEFUN(ar_addmod, (list), + struct list *list) +{ + if (!obfd) { + fprintf(stderr, _("%s: no open output archive\n"), program_name); + maybequit(); + } + else + { + while (list) { + bfd *abfd = bfd_openr(list->name, NULL); + if (!abfd) { + fprintf(stderr,_("%s: can't open file %s\n"), program_name, + list->name); + maybequit(); + } + else { + abfd->next = obfd->archive_head; + obfd->archive_head = abfd; + } + list = list->next; + } + } +} + + + +void +DEFUN_VOID(ar_clear) +{ +if (obfd) + obfd->archive_head = 0; +} + +void +DEFUN(ar_delete, (list), + struct list *list) +{ + if (!obfd) { + fprintf(stderr, _("%s: no open output archive\n"), program_name); + maybequit(); + } + else + { + while (list) { + /* Find this name in the archive */ + bfd *member = obfd->archive_head; + bfd **prev = &(obfd->archive_head); + int found = 0; + while (member) { + if (strcmp(member->filename, list->name) == 0) { + *prev = member->next; + found = 1; + } + else { + prev = &(member->next); + } + member = member->next; + } + if (!found) { + fprintf(stderr,_("%s: can't find module file %s\n"), program_name, + list->name); + maybequit(); + } + list = list->next; + } + } +} + + +void +DEFUN_VOID(ar_save) +{ + + if (!obfd) { + fprintf(stderr, _("%s: no open output archive\n"), program_name); + maybequit(); + } + else { + char *ofilename = xstrdup (bfd_get_filename (obfd)); + bfd_close(obfd); + + rename (ofilename, real_name); + obfd = 0; + free(ofilename); + } +} + + + +void +DEFUN(ar_replace, (list), + struct list *list) +{ + if (!obfd) { + fprintf(stderr, _("%s: no open output archive\n"), program_name); + maybequit(); + } + else + { + while (list) { + /* Find this name in the archive */ + bfd *member = obfd->archive_head; + bfd **prev = &(obfd->archive_head); + int found = 0; + while (member) + { + if (strcmp(member->filename, list->name) == 0) + { + /* Found the one to replace */ + bfd *abfd = bfd_openr(list->name, 0); + if (!abfd) + { + fprintf(stderr, _("%s: can't open file %s\n"), program_name, list->name); + maybequit(); + } + else { + *prev = abfd; + abfd->next = member->next; + found = 1; + } + } + else { + prev = &(member->next); + } + member = member->next; + } + if (!found) { + bfd *abfd = bfd_openr(list->name, 0); + fprintf(stderr,_("%s: can't find module file %s\n"), program_name, + list->name); + if (!abfd) + { + fprintf(stderr, _("%s: can't open file %s\n"), program_name, list->name); + maybequit(); + } + else + { + *prev = abfd; + } + } + + list = list->next; + } + } +} + +/* And I added this one */ +void +DEFUN_VOID(ar_list) +{ + if (!obfd) + { + fprintf(stderr, _("%s: no open output archive\n"), program_name); + maybequit(); + } + else { + bfd *abfd; + outfile = stdout; + verbose =1 ; + printf(_("Current open archive is %s\n"), bfd_get_filename (obfd)); + for (abfd = obfd->archive_head; + abfd != (bfd *)NULL; + abfd = abfd->next) + { + ar_directory_doer (abfd, (bfd *) NULL); + } + } +} + + +void +DEFUN_VOID(ar_end) +{ + if (obfd) + { + fclose((FILE *)(obfd->iostream)); + unlink(bfd_get_filename (obfd)); + } +} +void +DEFUN(ar_extract,(list), + struct list *list) +{ + if (!obfd) + { + + fprintf(stderr, _("%s: no open archive\n"), program_name); + maybequit(); + } + else + { + while (list) { + /* Find this name in the archive */ + bfd *member = obfd->archive_head; + int found = 0; + while (member && !found) + { + if (strcmp(member->filename, list->name) == 0) + { + extract_file(member); + found = 1; + } + + member = member->next; + } + if (!found) { + bfd_openr(list->name, 0); + fprintf(stderr,_("%s: can't find module file %s\n"), program_name, + list->name); + + } + list = list->next; + } + } +} |