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