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.
This commit is contained in:
Steve Chamberlain 1992-04-15 21:36:37 +00:00
parent 4a11eef2eb
commit c0cc691258
6 changed files with 913 additions and 202 deletions

View File

@ -36,6 +36,10 @@ alloca.c
am29k-pinsn.c am29k-pinsn.c
ar.1 ar.1
ar.c ar.c
arlex.l
arsup.c
arsup.h
arparse.y
binutils.texi binutils.texi
bucomm.c bucomm.c
bucomm.h bucomm.h

View File

@ -29,18 +29,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "bucomm.h" #include "bucomm.h"
#include "aout/ar.h" #include "aout/ar.h"
#include "../bfd/libbfd.h" #include "../bfd/libbfd.h"
#include "arsup.h"
#include <stdio.h> #include <stdio.h>
#ifdef USG
#include <time.h>
#else
#include <sys/time.h> #include <sys/time.h>
#endif
#include <errno.h> #include <errno.h>
#define BUFSIZE 8192 #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, print_contents, (bfd * member));
PROTO(void, extract_file, (bfd * abfd)); PROTO(void, extract_file, (bfd * abfd));
PROTO(void, delete_members, (char **files_to_delete)); PROTO(void, delete_members, (char **files_to_delete));
@ -56,6 +57,7 @@ char *program_name = NULL;
bfd bogus_archive; bfd bogus_archive;
bfd *inarch; /* The input arch we're manipulating */ bfd *inarch; /* The input arch we're manipulating */
int mri_mode;
/* This flag distinguishes between ar and ranlib: /* This flag distinguishes between ar and ranlib:
1 means this is 'ranlib'; 0 means this is 'ar'. 1 means this is 'ranlib'; 0 means this is 'ar'.
-1 means if we should use argv[0] to decide. */ -1 means if we should use argv[0] to decide. */
@ -113,6 +115,52 @@ enum pos {
} }
#endif #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; boolean operation_alters_arch = false;
@ -126,196 +174,207 @@ main(argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
char *arg_ptr; char *arg_ptr;
char c; char c;
enum { enum {
none = 0, delete, replace, print_table, none = 0, delete, replace, print_table,
print_files, extract, move, quick_append print_files, extract, move, quick_append
} operation = none; } operation = none;
int arg_index; int arg_index;
char **files; char **files;
char *inarch_filename; char *inarch_filename;
char *temp; char *temp;
bfd_init();
bfd_init();
verbose = 1;
#ifdef GNU960 #ifdef GNU960
check_v960( argc, argv ); check_v960( argc, argv );
default_target = bfd_make_targ_name(BFD_COFF_FORMAT,HOST_BYTE_ORDER_BIG_P); default_target = bfd_make_targ_name(BFD_COFF_FORMAT,HOST_BYTE_ORDER_BIG_P);
#endif #endif
program_name = argv[0]; program_name = argv[0];
temp = strrchr(program_name, '/'); temp = strrchr(program_name, '/');
if (temp == (char *) NULL) if (temp == (char *) NULL)
temp = program_name; /* shouldn't happen, but... */ temp = program_name; /* shouldn't happen, but... */
else else
++temp; ++temp;
if (is_ranlib > 0 || (is_ranlib < 0 && strcmp(temp, "ranlib") == 0)) { if (is_ranlib > 0 || (is_ranlib < 0 && strcmp(temp, "ranlib") == 0)) {
if (argc < 2) if (argc < 2)
bfd_fatal("Too few command arguments."); bfd_fatal("Too few command arguments.");
ranlib_only(argv[1]); ranlib_only(argv[1]);
} }
if (argc == 2 && strcmp(argv[1],"-M") == 0) {
if (argc < 3) mri_emul();
bfd_fatal("Too few command arguments."); exit(0);
}
arg_ptr = argv[1]; if (argc < 3)
bfd_fatal("Too few command arguments.");
if (*arg_ptr == '-')
++arg_ptr; /* compatibility */ arg_ptr = argv[1];
while (c = *arg_ptr++) { if (*arg_ptr == '-')
switch (c) { ++arg_ptr; /* compatibility */
case 'd':
case 'm': while (c = *arg_ptr++) {
case 'p': switch (c) {
case 'q': case 'd':
case 'r': case 'm':
case 't': case 'p':
case 'x': case 'q':
if (operation != none) case 'r':
fatal("two different operation switches specified"); case 't':
switch (c) { case 'x':
case 'd': if (operation != none)
operation = delete; fatal("two different operation switches specified");
operation_alters_arch = true; switch (c) {
break; case 'd':
case 'm': operation = delete;
operation = move; operation_alters_arch = true;
operation_alters_arch = true; break;
break; case 'm':
case 'p': operation = move;
operation = print_files; operation_alters_arch = true;
break; break;
case 'q': case 'p':
operation = quick_append; operation = print_files;
operation_alters_arch = true; break;
break; case 'q':
case 'r': operation = quick_append;
operation = replace; operation_alters_arch = true;
operation_alters_arch = true; break;
break; case 'r':
case 't': operation = replace;
operation = print_table; operation_alters_arch = true;
break; break;
case 'x': case 't':
operation = extract; operation = print_table;
break; break;
} case 'x':
case 'l': operation = extract;
break; break;
case 'c': }
silent_create = 1; case 'l':
break; break;
case 'o': case 'c':
preserve_dates = 1; silent_create = 1;
break; break;
case 's': case 'o':
write_armap = true; preserve_dates = 1;
break; break;
case 'u': case 's':
newer_only = 1; write_armap = true;
break; break;
case 'v': case 'u':
verbose = 1; newer_only = 1;
break; break;
case 'a': case 'v':
postype = pos_after; verbose = 1;
break; break;
case 'b': case 'a':
postype = pos_before; postype = pos_after;
break; break;
case 'i': case 'b':
postype = pos_before; postype = pos_before;
break; break;
default: case 'i':
fatal("invalid option %c", c); 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) if ((operation == none || operation == print_table)
&& write_armap == true) && write_armap == true)
ranlib_only(argv[2]); ranlib_only(argv[2]);
if (operation == none) if (operation == none)
fatal("no operation specified"); fatal("no operation specified");
if (newer_only && operation != replace) if (newer_only && operation != replace)
fatal("'u' only meaningful with 'r' option."); fatal("'u' only meaningful with 'r' option.");
arg_index = 2; arg_index = 2;
if (postype != pos_default) if (postype != pos_default)
posname = argv[arg_index++]; posname = argv[arg_index++];
inarch_filename = argv[arg_index++]; inarch_filename = argv[arg_index++];
if (arg_index < argc) { if (arg_index < argc) {
files = argv + arg_index; files = argv + arg_index;
while (arg_index < argc) while (arg_index < argc)
if (!strcmp(argv[arg_index++], "__.SYMDEF")) { if (!strcmp(argv[arg_index++], "__.SYMDEF")) {
ignore_symdef = 1; ignore_symdef = 1;
break; break;
} }
} }
else else
files = NULL; files = NULL;
if (operation == quick_append) { if (operation == quick_append) {
if (files != NULL) if (files != NULL)
do_quick_append(inarch_filename, files); do_quick_append(inarch_filename, files);
exit(0); exit(0);
} }
open_inarch(inarch_filename); 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 0
if (operation == replace && inarch == &bogus_archive) { if (operation == replace && inarch == &bogus_archive) {
silent_create = 1; silent_create = 1;
do_quick_append(inarch_filename, 0); do_quick_append(inarch_filename, 0);
open_inarch(inarch_filename); open_inarch(inarch_filename);
} }
#endif #endif
switch (operation) { switch (operation) {
case print_table: case print_table:
map_over_members(print_descr, files, argc - 3); map_over_members(print_descr, files, argc - 3);
break; break;
case print_files: case print_files:
map_over_members(print_contents, files, argc - 3); map_over_members(print_contents, files, argc - 3);
break; break;
case extract: case extract:
map_over_members(extract_file, files, argc - 3); map_over_members(extract_file, files, argc - 3);
break; break;
case delete: case delete:
if (files != NULL) if (files != NULL)
delete_members(files); delete_members(files);
break; break;
case move: case move:
if (files != NULL) if (files != NULL)
move_members(files); move_members(files);
break; break;
case replace: case replace:
if (files != NULL || write_armap) if (files != NULL || write_armap)
replace_members(files); replace_members(files);
break; break;
/* Shouldn't happen! */ /* Shouldn't happen! */
default: default:
fprintf(stderr, "Sorry; this option not implemented.\n"); fprintf(stderr, "Sorry; this option not implemented.\n");
} }
}
return (0); return (0);
} /* main() */ } /* main() */
static static
@ -332,7 +391,7 @@ char *file;
return filename; return filename;
} }
static void void
open_inarch(archive_filename) open_inarch(archive_filename)
char *archive_filename; char *archive_filename;
{ {
@ -346,7 +405,8 @@ open_inarch(archive_filename)
if (!operation_alters_arch) { if (!operation_alters_arch) {
fprintf (stderr, "%s: %s not found.\n", program_name, fprintf (stderr, "%s: %s not found.\n", program_name,
archive_filename); archive_filename);
exit (1); maybequit();
return ;
} }
if (!silent_create) if (!silent_create)
fprintf(stderr, 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 void
@ -502,7 +521,7 @@ extract_file(abfd)
ostream = 0; ostream = 0;
if (size == 0) { if (size == 0) {
/* Seems like an abstraction violation, eh? Well it's OK! */ /* Seems like an abstraction violation, eh? Well it's OK! */
ostream = fopen(abfd->filename, "wb"); ostream = fopen(abfd->filename, FOPEN_WB);
if (!ostream) { if (!ostream) {
perror(abfd->filename); perror(abfd->filename);
exit(1); exit(1);
@ -520,7 +539,7 @@ extract_file(abfd)
/* See comment above; this saves disk arm motion */ /* See comment above; this saves disk arm motion */
if (!ostream) { if (!ostream) {
/* Seems like an abstraction violation, eh? Well it's OK! */ /* Seems like an abstraction violation, eh? Well it's OK! */
ostream = fopen(abfd->filename, "wb"); ostream = fopen(abfd->filename, FOPEN_WB);
if (!ostream) { if (!ostream) {
perror(abfd->filename); perror(abfd->filename);
exit(1); 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) { if (ofile == NULL) {
perror(program_name); perror(program_name);
exit(1); 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)); 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) if (ifile == NULL)
bfd_perror(program_name); bfd_perror(program_name);
@ -940,5 +959,8 @@ void
print_descr(abfd) print_descr(abfd)
bfd *abfd; bfd *abfd;
{ {
print_arelt_descr(abfd, verbose); print_arelt_descr(stdout,abfd, verbose);
} }

77
binutils/arlex.l Normal file
View File

@ -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; }

197
binutils/arparse.y Normal file
View File

@ -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;
}

382
binutils/arsup.c Normal file
View File

@ -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);
}
}
}

29
binutils/arsup.h Normal file
View File

@ -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();