home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / binutils-2.2.1 / binutils / arsup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-25  |  8.2 KB  |  439 lines

  1. /* arsup.c - Archive support for MRI compatibility */
  2.  
  3. /*   Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, 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. */
  29.  
  30. #include "bfd.h"
  31. #include "arsup.h"
  32. #include <sysdep.h>
  33. #include "bucomm.h"
  34. extern bfd *inarch;
  35. extern int verbose;
  36.  
  37. extern char *strdup();
  38.  
  39. void
  40. DEFUN(map_over_list,(function, list),
  41.       void            (*function) () AND
  42.       struct list           *list)
  43.  
  44. {
  45.   bfd            *head;
  46.  
  47.   if (list == 0) {
  48.     for (head = inarch->next; head; head = head->next){
  49.       function(head);
  50.     }
  51.   }
  52.   else {
  53.     /*
  54.       This may appear to be a baroque way of accomplishing what we want.
  55.       however we have to iterate over the filenames in order to notice where
  56.       a filename is requested but does not exist in the archive.  Ditto
  57.       mapping over each file each time -- we want to hack multiple
  58.       references.
  59.       */
  60.     struct list *ptr = list;
  61.  
  62.     for (ptr = list; ptr; ptr=ptr->next)
  63.     {
  64.       boolean         found = false;
  65.       bfd *prev = inarch;
  66.       for (head = inarch->next; head; head = head->next) 
  67.       {
  68.     if ((head->filename != NULL) &&
  69.         (!strcmp(ptr->name, head->filename))) 
  70.     {
  71.       found = true;
  72.       function(head, prev);
  73.  
  74.     }
  75.     prev = head;
  76.       }
  77.       if (!found)
  78.        fprintf(stderr, "No entry %s in archive.\n", ptr->name);
  79.     }
  80.   }
  81. }
  82.  
  83.  
  84. FILE *outfile;
  85. void
  86. DEFUN(ar_directory_doer,(abfd),
  87.       bfd *abfd)
  88. {
  89.     print_arelt_descr(outfile, abfd, verbose);
  90. }
  91.  
  92. void
  93. DEFUN(ar_directory,(ar_name, list, output),
  94.       char *ar_name AND
  95.       struct list *list AND
  96.       char *output)
  97. {
  98.   open_inarch(ar_name);
  99.   if (output)  {
  100.     outfile = fopen(output,"w");
  101.     if (outfile == 0) {
  102.       outfile =stdout;
  103.       fprintf(stderr,"Can't open file %s\n", output);
  104.       output = 0;
  105.     }
  106.   }
  107.   else 
  108.    outfile = stdout;
  109.  
  110.   map_over_list(ar_directory_doer, list);
  111.   bfd_close(inarch);
  112.   if (output)
  113.    fclose(outfile);
  114. }
  115.  
  116. void
  117. DEFUN_VOID(prompt)
  118. {
  119.   extern int interactive;
  120.   if (interactive) 
  121.   {
  122.     printf("AR >");
  123.     fflush(stdout); 
  124.   }
  125. }
  126.  
  127. void
  128. DEFUN_VOID(maybequit)
  129. {
  130. if (!interactive) 
  131.  exit(9);
  132. }
  133.  
  134.  
  135. bfd *obfd;
  136. char *real_name ; 
  137. void
  138. DEFUN(ar_open,(name, t),
  139.       char *name AND
  140.       int t)
  141.  
  142. {
  143.   char *tname = malloc(strlen(name)+10);
  144.   real_name = name;
  145.   sprintf(tname, "%s-tmp", name);
  146.   obfd = bfd_openw(tname, NULL);
  147.  
  148.   if (!obfd) {
  149.     fprintf(stderr,"%s: Can't open output archive %s\n", program_name,
  150.         tname);
  151.  
  152.     maybequit();
  153.   }
  154.   else {
  155.     if (!t) {
  156.       bfd **ptr;
  157.       bfd *element;
  158.       bfd *ibfd;
  159.       ibfd = bfd_openr(name, NULL);
  160.       if (!ibfd) {
  161.     fprintf(stderr,"%s: Can't open input archive %s\n",
  162.         program_name, name);
  163.     maybequit();
  164.     return;
  165.       }
  166.       if (bfd_check_format(ibfd, bfd_archive) != true) {
  167.     fprintf(stderr,"%s: file %s is not an archive\n", program_name,
  168.         name);
  169.     maybequit();
  170.     return;
  171.       }
  172.       ptr = &(obfd->archive_head);
  173.       element = bfd_openr_next_archived_file(ibfd, NULL);
  174.  
  175.       while (element) {
  176.     *ptr = element;
  177.     ptr = &element->next;
  178.     element = bfd_openr_next_archived_file(ibfd, element);
  179.       }
  180.     }
  181.  
  182.     bfd_set_format(obfd, bfd_archive);
  183.  
  184.     obfd->has_armap = 1;
  185.   }
  186. }
  187.  
  188.  
  189. void
  190. DEFUN(ar_addlib_doer, (abfd, prev),
  191.       bfd *abfd AND
  192.       bfd *prev)
  193. {
  194.   /* Add this module to the output bfd */
  195.   
  196.   prev->next = abfd->next;
  197.   abfd->next = obfd->archive_head;
  198.   obfd->archive_head = abfd;
  199. }
  200.  
  201. void
  202. DEFUN(ar_addlib, (name, list),
  203.       char *name AND
  204.       struct list *list)
  205. {
  206.   if (!obfd) {
  207.     fprintf(stderr, "%s: no output archive specified yet\n", program_name);
  208.     maybequit();
  209.   }
  210.   else {
  211.     if (open_inarch(name) ) {
  212.       map_over_list(ar_addlib_doer, list);
  213.     }
  214.     /* Don't close the bfd, since it will make the elements disasppear */
  215.   }
  216. }
  217.  
  218.  
  219.  
  220. void
  221. DEFUN(ar_addmod, (list),
  222.       struct list *list)
  223. {
  224.   if (!obfd) {
  225.     fprintf(stderr, "%s: no open output archive\n", program_name);
  226.     maybequit();
  227.   }
  228.   else 
  229.   {
  230.     while (list) {
  231.       bfd *abfd = bfd_openr(list->name, NULL);
  232.       if (!abfd)  {
  233.     fprintf(stderr,"%s: can't open file %s\n", program_name,
  234.         list->name);
  235.     maybequit();
  236.       }
  237.       else {
  238.     abfd->next = obfd->archive_head;
  239.     obfd->archive_head = abfd;
  240.       }
  241.       list = list->next;
  242.     }
  243.   }
  244. }
  245.  
  246.  
  247.  
  248. void
  249. DEFUN_VOID(ar_clear)
  250. {
  251. if (obfd) 
  252.  obfd->archive_head = 0;
  253. }
  254.  
  255. void
  256. DEFUN(ar_delete, (list),
  257.       struct list *list)
  258. {
  259.   if (!obfd) {
  260.     fprintf(stderr, "%s: no open output archive\n", program_name);
  261.     maybequit();
  262.   }
  263.   else 
  264.   {
  265.     while (list) {
  266.       /* Find this name in the archive */
  267.       bfd *member = obfd->archive_head;
  268.       bfd **prev = &(obfd->archive_head);
  269.       int found = 0;
  270.       while (member) {
  271.     if (strcmp(member->filename, list->name) == 0) {
  272.       *prev = member->next;
  273.       found = 1;
  274.     }
  275.     else {
  276.       prev = &(member->next);
  277.     }
  278.       member = member->next;
  279.       }
  280.       if (!found)  {
  281.     fprintf(stderr,"%s: can't find module file %s\n", program_name,
  282.         list->name);
  283.     maybequit();
  284.       }
  285.       list = list->next;
  286.     }
  287.   }
  288. }
  289.  
  290.  
  291. void
  292. DEFUN_VOID(ar_save)
  293. {
  294.  
  295.   if (!obfd) {
  296.     fprintf(stderr, "%s: no open output archive\n", program_name);
  297.     maybequit();
  298.   }
  299.   else {
  300.     char *ofilename = strdup(obfd->filename);
  301.     bfd_close(obfd);
  302.     
  303.     unlink(real_name);
  304.     link(ofilename, real_name);
  305.     unlink(ofilename);
  306.     obfd = 0;
  307.     free(ofilename);
  308.   }
  309. }
  310.  
  311.  
  312.  
  313. void
  314. DEFUN(ar_replace, (list),
  315.       struct list *list)
  316. {
  317.   if (!obfd) {
  318.     fprintf(stderr, "%s: no open output archive\n", program_name);
  319.     maybequit();
  320.   }
  321.   else 
  322.   {
  323.     while (list) {
  324.       /* Find this name in the archive */
  325.       bfd *member = obfd->archive_head;
  326.       bfd **prev = &(obfd->archive_head);
  327.       int found = 0;
  328.       while (member) 
  329.       {
  330.     if (strcmp(member->filename, list->name) == 0) 
  331.     {
  332.       /* Found the one to replace */
  333.       bfd *abfd = bfd_openr(list->name, 0);
  334.       if (!abfd) 
  335.       {
  336.         fprintf(stderr, "%s: can't open file %s\n", program_name, list->name);
  337.         maybequit();
  338.       }
  339.       else {
  340.         *prev = abfd;
  341.         abfd->next = member->next;
  342.         found = 1;
  343.       }
  344.     }
  345.     else {
  346.       prev = &(member->next);
  347.     }
  348.     member = member->next;
  349.       }
  350.       if (!found)  {
  351.     bfd *abfd = bfd_openr(list->name, 0);
  352.     fprintf(stderr,"%s: can't find module file %s\n", program_name,
  353.         list->name);
  354.     if (!abfd) 
  355.     {
  356.       fprintf(stderr, "%s: can't open file %s\n", program_name, list->name);
  357.       maybequit();
  358.     }
  359.     else 
  360.     {
  361.       *prev = abfd;
  362.     }
  363.       }
  364.  
  365.     list = list->next;
  366.     }
  367.   }
  368. }
  369.  
  370. /* And I added this one */
  371. void
  372. DEFUN_VOID(ar_list)
  373. {
  374.   if (!obfd) 
  375.   {
  376.     fprintf(stderr, "%s: no open output archive\n", program_name);
  377.     maybequit();
  378.   }
  379.   else {
  380.     bfd *abfd;
  381.     outfile = stdout;
  382.     verbose =1 ;
  383.     printf("Current open archive is %s\n", obfd->filename);
  384.     for (abfd = obfd->archive_head;
  385.      abfd != (bfd *)NULL;
  386.      abfd = abfd->next) 
  387.     {
  388.       ar_directory_doer(abfd);
  389.     }
  390.   }
  391. }
  392.  
  393.  
  394. void 
  395. DEFUN_VOID(ar_end)
  396. {
  397.   if (obfd)
  398.   {
  399.     fclose((FILE *)(obfd->iostream));
  400.     unlink(obfd->filename);
  401.   }
  402. }
  403. void
  404. DEFUN(ar_extract,(list),
  405.       struct list *list)
  406. {
  407.   if (!obfd) 
  408.   {
  409.  
  410.     fprintf(stderr, "%s: no open  archive\n", program_name);
  411.     maybequit();
  412.   }
  413.   else 
  414.   {
  415.     while (list) {
  416.       /* Find this name in the archive */
  417.       bfd *member = obfd->archive_head;
  418.       int found = 0;
  419.       while (member && !found) 
  420.       {
  421.     if (strcmp(member->filename, list->name) == 0) 
  422.     {
  423.       extract_file(member);
  424.       found = 1;
  425.       }
  426.  
  427.     member = member->next;
  428.       }
  429.       if (!found)  {
  430.     bfd *abfd = bfd_openr(list->name, 0);
  431.     fprintf(stderr,"%s: can't find module file %s\n", program_name,
  432.         list->name);
  433.  
  434.       }
  435.       list = list->next;
  436.     }
  437.   }
  438. }
  439.