home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / make3_60.lzh / MAKE3_60 / AR.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  4KB  |  173 lines

  1. /* Copyright (C) 1988-1991 Free Software Foundation, Inc.
  2. This file is part of GNU Make.
  3.  
  4. GNU Make is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8.  
  9. GNU Make is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with GNU Make; see the file COPYING.  If not, write to
  16. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include "make.h"
  19. #include "file.h"
  20.  
  21.  
  22. /* Defined in arscan.c.  */
  23. extern long int ar_scan ();
  24. extern int ar_member_touch ();
  25. extern int ar_name_equal ();
  26.  
  27.  
  28. /* Return nonzero if NAME is an archive-member reference, zero if not.
  29.    An archive-member reference is a name like `lib(member)'.
  30.    If a name like `lib((entry))' is used, a fatal error is signaled at
  31.    the attempt to use this unsupported feature.  */
  32.  
  33. int
  34. ar_name (name)
  35.      char *name;
  36. {
  37.   char *p = index (name, '('), *end = name + strlen (name) - 1;
  38.   
  39.   if (p == 0 || p == name || *end != ')')
  40.     return 0;
  41.  
  42.   if (p[1] == '(' && end[-1] == ')')
  43.     fatal ("attempt to use unsupported feature: `%s'", name);
  44.  
  45.   return 1;
  46. }
  47.  
  48.  
  49. /* Parse the archive-member reference NAME into the archive and member names.
  50.    Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil;
  51.    put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil.  */
  52.  
  53. void
  54. ar_parse_name (name, arname_p, memname_p)
  55.      char *name, **arname_p, **memname_p;
  56. {
  57.   char *p = index (name, '('), *end = name + strlen (name) - 1;
  58.  
  59.   if (arname_p != 0)
  60.     *arname_p = savestring (name, p - name);
  61.  
  62.   if (memname_p != 0)
  63.     *memname_p = savestring (p + 1, end - (p + 1));
  64. }  
  65.  
  66. static long int ar_member_date_1 ();
  67.  
  68. /* Return the modtime of NAME.  */
  69.  
  70. time_t
  71. ar_member_date (name)
  72.      char *name;
  73. {
  74.   char *arname;
  75.   int arname_used = 0;
  76.   char *memname;
  77.   long int val;
  78.  
  79.   ar_parse_name (name, &arname, &memname);
  80.  
  81.   /* Make sure we know the modtime of the archive itself because
  82.      we are likely to be called just before commands to remake a
  83.      member are run, and they will change the archive itself.  */
  84.   {
  85.     struct file *arfile;
  86.     arfile = lookup_file (arname);
  87.     if (arfile == 0)
  88.       {
  89.     arfile = enter_file (arname);
  90.     arname_used = 1;
  91.       }
  92.  
  93.     (void) f_mtime (arfile, 0);
  94.   }
  95.  
  96.   val = ar_scan (arname, ar_member_date_1, (long int) memname);
  97.  
  98.   if (!arname_used)
  99.     free (arname);
  100.   free (memname);
  101.  
  102.   return (val <= 0 ? (time_t) -1 : (time_t) val);
  103. }
  104.  
  105. /* This function is called by `ar_scan' to find which member to look at.  */
  106.  
  107. /* ARGSUSED */
  108. static long int
  109. ar_member_date_1 (desc, mem, hdrpos, datapos, size, date, uid, gid, mode, name)
  110.      int desc;
  111.      char *mem;
  112.      long int hdrpos, datapos, size, date;
  113.      int uid, gid, mode;
  114.      char *name;
  115. {
  116.   return ar_name_equal (name, mem) ? date : 0;
  117. }
  118.  
  119. /* Set the archive-member NAME's modtime to now.  */
  120.  
  121. int
  122. ar_touch (name)
  123.      char *name;
  124. {
  125.   char *arname, *memname;
  126.   int arname_used = 0;
  127.   register int val;
  128.  
  129.   ar_parse_name (name, &arname, &memname);
  130.  
  131.   /* Make sure we know the modtime of the archive itself before we
  132.      touch the member, since this will change the archive itself.  */
  133.   {
  134.     struct file *arfile;
  135.     arfile = lookup_file (arname);
  136.     if (arfile == 0)
  137.       {
  138.     arfile = enter_file (arname);
  139.     arname_used = 1;
  140.       }
  141.  
  142.     (void) f_mtime (arfile, 0);
  143.   }
  144.  
  145.   val = 1;
  146.   switch (ar_member_touch (arname, memname))
  147.     {
  148.     case -1:
  149.       error ("touch: Archive `%s' does not exist", arname);
  150.       break;
  151.     case -2:
  152.       error ("touch: `%s' is not a valid archive", arname);
  153.       break;
  154.     case -3:
  155.       perror_with_name ("touch: ", arname);
  156.       break;
  157.     case 1:
  158.       error ("touch: Member `%s' does not exist in `%s'", memname, arname);
  159.       break;
  160.     case 0:
  161.       val = 0;
  162.       break;
  163.     default:
  164.       error ("touch: Bad return code from ar_member_touch on `%s'", name);
  165.     }
  166.  
  167.   if (!arname_used)
  168.     free (arname);
  169.   free (memname);
  170.  
  171.   return val;
  172. }
  173.