aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1992-04-15 21:36:37 +0000
committerSteve Chamberlain <sac@cygnus>1992-04-15 21:36:37 +0000
commitc0cc691258938d3c280b06531b951936b93dc921 (patch)
tree9af53c44f19477b1b442bc080eb12b77ed3f1726 /binutils
parent4a11eef2ebf99f527ee5452386a5f2a099ed6b8b (diff)
downloadgdb-c0cc691258938d3c280b06531b951936b93dc921.zip
gdb-c0cc691258938d3c280b06531b951936b93dc921.tar.gz
gdb-c0cc691258938d3c280b06531b951936b93dc921.tar.bz2
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.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/.Sanitize4
-rw-r--r--binutils/ar.c430
-rw-r--r--binutils/arlex.l77
-rw-r--r--binutils/arparse.y197
-rw-r--r--binutils/arsup.c382
-rw-r--r--binutils/arsup.h29
6 files changed, 915 insertions, 204 deletions
diff --git a/binutils/.Sanitize b/binutils/.Sanitize
index 074f50c..4cc1130 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 cdee758..244a15a 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 <stdio.h>
+#ifdef USG
+#include <time.h>
+#else
#include <sys/time.h>
+#endif
#include <errno.h>
#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 0000000..47f8361
--- /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 <ansidecl.h>
+#include <sysdep.h>
+#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 0000000..dccdf8e
--- /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 <sysdep.h>
+#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 <name> 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 <list> modulelist
+%type <list> modulename
+%type <name> 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 0000000..ee7e4e9
--- /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 <sysdep.h>
+#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 0000000..a750c08
--- /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();