From: Steve Chamberlain Date: Wed, 15 Apr 1992 21:36:37 +0000 (+0000) Subject: Wed Apr 15 14:33:07 1992 Steve Chamberlain (sac@thepub.cygnus.com) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0cc691258938d3c280b06531b951936b93dc921;p=binutils-gdb.git Wed Apr 15 14:33:07 1992 Steve Chamberlain (sac@thepub.cygnus.com) * arsup.c, arsup.h, arparse.y, arlex.l: support for archive scripting language. --- diff --git a/binutils/.Sanitize b/binutils/.Sanitize index 074f50c5e6c..4cc1130f36c 100644 --- a/binutils/.Sanitize +++ b/binutils/.Sanitize @@ -36,6 +36,10 @@ alloca.c am29k-pinsn.c ar.1 ar.c +arlex.l +arsup.c +arsup.h +arparse.y binutils.texi bucomm.c bucomm.h diff --git a/binutils/ar.c b/binutils/ar.c index cdee7589c7f..244a15a1bd3 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -29,18 +29,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bucomm.h" #include "aout/ar.h" #include "../bfd/libbfd.h" +#include "arsup.h" #include +#ifdef USG +#include +#else #include +#endif #include #define BUFSIZE 8192 -/* PROTO (void, open_inarch, (char *archive_filename)); */ -#ifdef __STDC__ -static void open_inarch(char *archive_filename); -#else -static void open_inarch(); -#endif /* __STDC__ */ -PROTO(void, map_over_members, (void (*function) (), char **files, int count)); +void EXFUN(open_inarch,(char *archive_filename)); + + PROTO(void, print_contents, (bfd * member)); PROTO(void, extract_file, (bfd * abfd)); PROTO(void, delete_members, (char **files_to_delete)); @@ -56,6 +57,7 @@ char *program_name = NULL; bfd bogus_archive; bfd *inarch; /* The input arch we're manipulating */ +int mri_mode; /* This flag distinguishes between ar and ranlib: 1 means this is 'ranlib'; 0 means this is 'ar'. -1 means if we should use argv[0] to decide. */ @@ -113,6 +115,52 @@ enum pos { } #endif +int interactive = 0; +void +DEFUN_VOID(mri_emul) +{ + interactive = isatty(fileno(stdin)) ; + yyparse(); +} + +/* + If count is 0, then function is called once on each entry. if nonzero, + count is the length of the files chain; function is called on each entry + whose name matches one in files +*/ +void +DEFUN(map_over_members,(function, files, count), + void (*function) () AND + char **files AND + int count) +{ + bfd *head; + + if (count == 0) { + for (head = inarch->next; head; head = head->next) + function(head); + return; + } + /* + 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 (; count > 0; files++, count--) { + boolean found = false; + for (head = inarch->next; head; head = head->next) + if ((head->filename != NULL) && + (!strcmp(*files, head->filename))) { + found = true; + function(head); + } + if (!found) + fprintf(stderr, "No entry %s in archive.\n", *files); + } +} boolean operation_alters_arch = false; @@ -126,196 +174,207 @@ main(argc, argv) int argc; char **argv; { - char *arg_ptr; - char c; - enum { - none = 0, delete, replace, print_table, - print_files, extract, move, quick_append - } operation = none; - int arg_index; - char **files; - char *inarch_filename; - char *temp; - - bfd_init(); - + char *arg_ptr; + char c; + enum { + none = 0, delete, replace, print_table, + print_files, extract, move, quick_append + } operation = none; + int arg_index; + char **files; + char *inarch_filename; + char *temp; + + bfd_init(); +verbose = 1; #ifdef GNU960 - check_v960( argc, argv ); - default_target = bfd_make_targ_name(BFD_COFF_FORMAT,HOST_BYTE_ORDER_BIG_P); + check_v960( argc, argv ); + default_target = bfd_make_targ_name(BFD_COFF_FORMAT,HOST_BYTE_ORDER_BIG_P); #endif - program_name = argv[0]; - - temp = strrchr(program_name, '/'); - if (temp == (char *) NULL) - temp = program_name; /* shouldn't happen, but... */ - else - ++temp; - if (is_ranlib > 0 || (is_ranlib < 0 && strcmp(temp, "ranlib") == 0)) { - if (argc < 2) - bfd_fatal("Too few command arguments."); - ranlib_only(argv[1]); - } - - - if (argc < 3) - bfd_fatal("Too few command arguments."); - - arg_ptr = argv[1]; - - if (*arg_ptr == '-') - ++arg_ptr; /* compatibility */ - - while (c = *arg_ptr++) { - switch (c) { - case 'd': - case 'm': - case 'p': - case 'q': - case 'r': - case 't': - case 'x': - if (operation != none) - fatal("two different operation switches specified"); - switch (c) { - case 'd': - operation = delete; - operation_alters_arch = true; - break; - case 'm': - operation = move; - operation_alters_arch = true; - break; - case 'p': - operation = print_files; - break; - case 'q': - operation = quick_append; - operation_alters_arch = true; - break; - case 'r': - operation = replace; - operation_alters_arch = true; - break; - case 't': - operation = print_table; - break; - case 'x': - operation = extract; - break; - } - case 'l': - break; - case 'c': - silent_create = 1; - break; - case 'o': - preserve_dates = 1; - break; - case 's': - write_armap = true; - break; - case 'u': - newer_only = 1; - break; - case 'v': - verbose = 1; - break; - case 'a': - postype = pos_after; - break; - case 'b': - postype = pos_before; - break; - case 'i': - postype = pos_before; - break; - default: - fatal("invalid option %c", c); - } + program_name = argv[0]; + + temp = strrchr(program_name, '/'); + if (temp == (char *) NULL) + temp = program_name; /* shouldn't happen, but... */ + else + ++temp; + if (is_ranlib > 0 || (is_ranlib < 0 && strcmp(temp, "ranlib") == 0)) { + if (argc < 2) + bfd_fatal("Too few command arguments."); + ranlib_only(argv[1]); + } + + if (argc == 2 && strcmp(argv[1],"-M") == 0) { + mri_emul(); + exit(0); + } + if (argc < 3) + bfd_fatal("Too few command arguments."); + + arg_ptr = argv[1]; + + if (*arg_ptr == '-') + ++arg_ptr; /* compatibility */ + + while (c = *arg_ptr++) { + switch (c) { + case 'd': + case 'm': + case 'p': + case 'q': + case 'r': + case 't': + case 'x': + if (operation != none) + fatal("two different operation switches specified"); + switch (c) { + case 'd': + operation = delete; + operation_alters_arch = true; + break; + case 'm': + operation = move; + operation_alters_arch = true; + break; + case 'p': + operation = print_files; + break; + case 'q': + operation = quick_append; + operation_alters_arch = true; + break; + case 'r': + operation = replace; + operation_alters_arch = true; + break; + case 't': + operation = print_table; + break; + case 'x': + operation = extract; + break; + } + case 'l': + break; + case 'c': + silent_create = 1; + break; + case 'o': + preserve_dates = 1; + break; + case 's': + write_armap = true; + break; + case 'u': + newer_only = 1; + break; + case 'v': + verbose = 1; + break; + case 'a': + postype = pos_after; + break; + case 'b': + postype = pos_before; + break; + case 'i': + postype = pos_before; + break; + case 'M': + + mri_mode = 1; + break; + default: + fatal("invalid option %c", c); } + } + if (mri_mode) { + mri_emul(); + } + else { if ((operation == none || operation == print_table) && write_armap == true) - ranlib_only(argv[2]); + ranlib_only(argv[2]); if (operation == none) - fatal("no operation specified"); + fatal("no operation specified"); if (newer_only && operation != replace) - fatal("'u' only meaningful with 'r' option."); + fatal("'u' only meaningful with 'r' option."); arg_index = 2; if (postype != pos_default) - posname = argv[arg_index++]; + posname = argv[arg_index++]; inarch_filename = argv[arg_index++]; if (arg_index < argc) { - files = argv + arg_index; - while (arg_index < argc) - if (!strcmp(argv[arg_index++], "__.SYMDEF")) { - ignore_symdef = 1; - break; - } + files = argv + arg_index; + while (arg_index < argc) + if (!strcmp(argv[arg_index++], "__.SYMDEF")) { + ignore_symdef = 1; + break; + } } else - files = NULL; + files = NULL; if (operation == quick_append) { - if (files != NULL) - do_quick_append(inarch_filename, files); - exit(0); + if (files != NULL) + do_quick_append(inarch_filename, files); + exit(0); } open_inarch(inarch_filename); /* - If we have no archive, and we've been asked to replace then create one - */ + If we have no archive, and we've been asked to replace then create one + */ #if 0 if (operation == replace && inarch == &bogus_archive) { - silent_create = 1; - do_quick_append(inarch_filename, 0); - open_inarch(inarch_filename); + silent_create = 1; + do_quick_append(inarch_filename, 0); + open_inarch(inarch_filename); } #endif switch (operation) { - case print_table: - map_over_members(print_descr, files, argc - 3); - break; + case print_table: + map_over_members(print_descr, files, argc - 3); + break; - case print_files: - map_over_members(print_contents, files, argc - 3); - break; + case print_files: + map_over_members(print_contents, files, argc - 3); + break; - case extract: - map_over_members(extract_file, files, argc - 3); - break; + case extract: + map_over_members(extract_file, files, argc - 3); + break; - case delete: - if (files != NULL) - delete_members(files); - break; + case delete: + if (files != NULL) + delete_members(files); + break; - case move: - if (files != NULL) - move_members(files); - break; + case move: + if (files != NULL) + move_members(files); + break; - case replace: - if (files != NULL || write_armap) - replace_members(files); - break; + case replace: + if (files != NULL || write_armap) + replace_members(files); + break; - /* Shouldn't happen! */ - default: - fprintf(stderr, "Sorry; this option not implemented.\n"); + /* Shouldn't happen! */ + default: + fprintf(stderr, "Sorry; this option not implemented.\n"); } - - return (0); + } + return (0); } /* main() */ static @@ -332,7 +391,7 @@ char *file; return filename; } -static void + void open_inarch(archive_filename) char *archive_filename; { @@ -346,7 +405,8 @@ open_inarch(archive_filename) if (!operation_alters_arch) { fprintf (stderr, "%s: %s not found.\n", program_name, archive_filename); - exit (1); + maybequit(); + return ; } if (!silent_create) fprintf(stderr, @@ -390,47 +450,6 @@ open_inarch(archive_filename) -/* - If count is 0, then function is called once on each entry. if nonzero, - count is the length of the files chain; function is called on each entry - whose name matches one in files -*/ -void -map_over_members(function, files, count) - void (*function) (); - char **files; - int count; -{ - bfd *head; - - - - - if (count == 0) { - for (head = inarch->next; head; head = head->next) - function(head); - return; - } - /* - 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 (; count > 0; files++, count--) { - boolean found = false; - for (head = inarch->next; head; head = head->next) - if ((head->filename != NULL) && - (!strcmp(*files, head->filename))) { - found = true; - function(head); - } - if (!found) - fprintf(stderr, "No entry %s in archive.\n", *files); - } -} void @@ -502,7 +521,7 @@ extract_file(abfd) ostream = 0; if (size == 0) { /* Seems like an abstraction violation, eh? Well it's OK! */ - ostream = fopen(abfd->filename, "wb"); + ostream = fopen(abfd->filename, FOPEN_WB); if (!ostream) { perror(abfd->filename); exit(1); @@ -520,7 +539,7 @@ extract_file(abfd) /* See comment above; this saves disk arm motion */ if (!ostream) { /* Seems like an abstraction violation, eh? Well it's OK! */ - ostream = fopen(abfd->filename, "wb"); + ostream = fopen(abfd->filename, FOPEN_WB); if (!ostream) { perror(abfd->filename); exit(1); @@ -580,7 +599,7 @@ do_quick_append(archive_filename, files_to_append) } - ofile = fopen(archive_filename, "a+b"); + ofile = fopen(archive_filename, FOPEN_AUB); if (ofile == NULL) { perror(program_name); exit(1); @@ -621,7 +640,7 @@ do_quick_append(archive_filename, files_to_append) BFD_SEND(temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr)); - ifile = fopen(*files_to_append, "rb"); + ifile = fopen(*files_to_append, FOPEN_RB); if (ifile == NULL) bfd_perror(program_name); @@ -940,5 +959,8 @@ void print_descr(abfd) bfd *abfd; { - print_arelt_descr(abfd, verbose); + print_arelt_descr(stdout,abfd, verbose); } + + + diff --git a/binutils/arlex.l b/binutils/arlex.l new file mode 100644 index 00000000000..47f8361bce1 --- /dev/null +++ b/binutils/arlex.l @@ -0,0 +1,77 @@ +%{ +/* arlex.l - Strange script language lexer */ + +/* Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Contributed by Steve Chamberlain + sac@cygnus.com + +*/ +#define DONTDECLARE_MALLOC +#include +#include +#include "arparse.h" +int linenumber; +%} +%% + +"ADDLIB" { return ADDLIB; } +"ADDMOD" { return ADDMOD; } +"CLEAR" { return CLEAR; } +"CREATE" { return CREATE; } +"DELETE" { return DELETE; } +"DIRECTORY" { return DIRECTORY; } +"END" { return END; } +"EXTRACT" { return EXTRACT; } +"FULLDIR" { return FULLDIR; } +"HELP" { return HELP; } +"LIST" { return LIST; } +"OPEN" { return OPEN; } +"REPLACE" { return REPLACE; } +"VERBOSE" { return VERBOSE; } +"SAVE" { return SAVE; } +"addlib" { return ADDLIB; } +"addmod" { return ADDMOD; } +"clear" { return CLEAR; } +"create" { return CREATE; } +"delete" { return DELETE; } +"directory" { return DIRECTORY; } +"end" { return END; } +"extract" { return EXTRACT; } +"fulldir" { return FULLDIR; } +"help" { return HELP; } +"list" { return LIST; } +"open" { return OPEN; } +"replace" { return REPLACE; } +"verbose" { return VERBOSE; } +"save" { return SAVE; } +"+\n" { linenumber ++; } +"(" { return '('; } +")" { return ')'; } +"," { return ','; } +[A-Za-z0-9/$:.\-]+ { + yylval.name = strdup(yytext); + return FILENAME; + } +"*".* { } +";".* { } +" " { } +"\n" { linenumber ++; return NEWLINE; } + diff --git a/binutils/arparse.y b/binutils/arparse.y new file mode 100644 index 00000000000..dccdf8e3633 --- /dev/null +++ b/binutils/arparse.y @@ -0,0 +1,197 @@ +%{ +/* arparse.y - Stange script language parser */ + +/* Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Contributed by Steve Chamberlain + sac@cygnus.com + +*/ +#define DONTDECLARE_MALLOC +#include "bfd.h" +#include +#include "arsup.h" +extern int interactive; +extern bfd *inarch; +extern int verbose; +void (*command)(); +FILE *listing; +%} + +%union { + char *name; +struct list *list ; + +}; + +%token NEWLINE +%token VERBOSE +%token FILENAME +%token ADDLIB +%token LIST +%token ADDMOD +%token CLEAR +%token CREATE +%token DELETE +%token DIRECTORY +%token END +%token EXTRACT +%token FULLDIR +%token HELP +%token QUIT +%token REPLACE +%token SAVE +%token OPEN + +%type modulelist +%type modulename +%type optional_filename +%% + +start: + { prompt(); } session + ; + +session: + session command_line + | + ; + +command_line: + command NEWLINE { prompt(); } + +command: + open_command + | create_command + | verbose_command + | directory_command + | addlib_command + | clear_command + | addmod_command + | save_command + | replace_command + | delete_command + | list_command + | END { return 0; } + | error + | + ; + + +replace_command: + REPLACE modulename + { ar_replace($2); } + ; + +clear_command: + CLEAR + { ar_clear(); } + ; + +delete_command: + DELETE modulename + { ar_delete($2); } + ; +addmod_command: + ADDMOD modulename + { ar_addmod($2); } + ; + +list_command: + LIST + { ar_list(); } + ; + +save_command: + SAVE + { ar_save(); } + ; + + + +open_command: + OPEN FILENAME + { ar_open($2,0); } + ; + +create_command: + CREATE FILENAME + { ar_open($2,1); } + ; + + +addlib_command: + ADDLIB FILENAME modulelist + { ar_addlib($2,$3); } + ; +directory_command: + DIRECTORY FILENAME modulelist optional_filename + { ar_directory($2, $3, $4); } + ; + + + +optional_filename: + FILENAME + { $$ = $1; } + | { $$ = 0; } + ; + +modulelist: + '(' modulename ')' + { $$ = $2; } + | + { $$ = 0; } + ; + +modulename: + modulename optcomma FILENAME + { struct list *n = (struct list *) malloc(sizeof(struct list)); + n->next = $1; + n->name = $3; + $$ = n; + } + | { $$ = 0; } + ; + + +optcomma: + ',' + | + ; + + +verbose_command: + VERBOSE + { verbose = !verbose; } + ; + + +%% + + +int +yyerror(x) +char *x; +{ + extern int linenumber; + printf("Synax error in archive script, line %d\n", linenumber + 1); + return 0; +} diff --git a/binutils/arsup.c b/binutils/arsup.c new file mode 100644 index 00000000000..ee7e4e9b2b5 --- /dev/null +++ b/binutils/arsup.c @@ -0,0 +1,382 @@ +/* arsup.c - Archive support for MRI compatibility */ + +/* Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, 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 +#include "bucomm.h" +extern bfd *inarch; +extern int verbose; + + + +void +DEFUN(map_over_list,(function, list), + void (*function) () AND + struct list *list) + +{ + bfd *head; + + if (list == 0) { + for (head = inarch->next; head; head = head->next){ + function(head); + } + } + else { + /* + 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. + */ + struct list *ptr = list; + + for (ptr = list; ptr; ptr=ptr->next) + { + boolean found = false; + bfd *prev = inarch; + for (head = inarch->next; head; head = head->next) + { + if ((head->filename != NULL) && + (!strcmp(ptr->name, head->filename))) + { + found = true; + function(head, prev); + + } + prev = head; + } + if (!found) + fprintf(stderr, "No entry %s in archive.\n", ptr->name); + } + } +} + + +FILE *outfile; +void +DEFUN(ar_directory_doer,(abfd), + bfd *abfd) +{ + print_arelt_descr(outfile, abfd, verbose); +} + +void +DEFUN(ar_directory,(ar_name, list, output), + char *ar_name AND + struct list *list AND + char *output) +{ + open_inarch(ar_name); + 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(ar_directory_doer, list); + bfd_close(inarch); + if (output) + fclose(outfile); +} + +void +DEFUN_VOID(prompt) +{ + extern int interactive; + if (interactive) + { + printf("AR >"); + fflush(stdout); + } +} + +void +DEFUN_VOID(maybequit) +{ +if (!interactive) + exit(9); +} + + +bfd *obfd; +char *real_name ; +void +DEFUN(ar_open,(name, t), + char *name AND + int t) + +{ + char *tname = malloc(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 (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; + } +} + + +void +DEFUN(ar_addlib_doer, (abfd, prev), + bfd *abfd AND + bfd *prev) +{ + /* Add this module to the output bfd */ + + prev->next = abfd->next; + abfd->next = obfd->archive_head; + obfd->archive_head = abfd; +} + +void +DEFUN(ar_addlib, (name, list), + char *name AND + struct list *list) +{ + if (!obfd) { + fprintf(stderr, "%s: no output archive specified yet\n", program_name); + maybequit(); + } + else { + if (open_inarch(name) ) { + map_over_list(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 { + bfd_close(obfd); + unlink(real_name); + link(obfd->filename, real_name); + unlink(obfd->filename); + obfd = 0; + } +} + + + +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", obfd->filename); + for (abfd = obfd->archive_head; + abfd != (bfd *)NULL; + abfd = abfd->next) + { + ar_directory_doer(abfd); + } + } +} diff --git a/binutils/arsup.h b/binutils/arsup.h new file mode 100644 index 00000000000..a750c083cde --- /dev/null +++ b/binutils/arsup.h @@ -0,0 +1,29 @@ + + + + +void EXFUN( map_over_members, (void (*function) (), char **files, int count)); + + + + + + struct list { + char *name; + struct list *next; + } ; + +void EXFUN(maybequit,(void)); +void EXFUN(prompt,(void)); +void EXFUN(ar_clear,(void)); +void EXFUN(ar_replace,(struct list *)); +void EXFUN(ar_delete,(struct list *)); +void EXFUN(ar_save, (void)); +void EXFUN(ar_list, (void)); +void EXFUN(ar_open, (char *, int)); +void EXFUN(ar_directory,(char *, struct list *, char *)); +void EXFUN(ar_addmod, (struct list *)); +void EXFUN(ar_addlib, (char *, struct list *)); +int interactive; + +int yyparse();