1 /* Dependency generator for Makefile fragments.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 Contributed by Zack Weinberg, Mar 2000
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program 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 this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding! */
27 static const char *munge
PARAMS ((const char *));
28 static const char *base_name
PARAMS ((const char *));
31 # define OBJECT_SUFFIX ".o"
34 /* Given a filename, quote characters in that filename which are
35 significant to Make. Note that it's not possible to quote all such
36 characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
37 not properly handled. It isn't possible to get this right in any
38 current version of Make. (??? Still true? Old comment referred to
49 for (p
= filename
, len
= 0; *p
; p
++, len
++)
55 /* GNU make uses a weird quoting scheme for white space.
56 A space or tab preceded by 2N+1 backslashes represents
57 N backslashes followed by space; a space or tab
58 preceded by 2N backslashes represents N backslashes at
59 the end of a file name; and backslashes in other
60 contexts should not be doubled. */
61 for (q
= p
- 1; q
< filename
&& q
[-1] == '\\'; q
--)
67 /* '$' is quoted by doubling it. This can mishandle things
68 like "$(" but there's no easy fix. */
74 /* Now we know how big to make the buffer. */
75 buffer
= malloc (len
+ 1);
77 for (p
= filename
, dst
= buffer
; *p
; p
++, dst
++)
83 for (q
= p
- 1; filename
< q
&& q
[-1] == '\\'; q
--)
102 /* Given a pathname, calculate the non-directory part. This always
103 knows how to handle Unix-style pathnames, and understands VMS and
104 DOS paths on those systems. */
105 /* Find the base name of a (partial) pathname FNAME.
106 Returns a pointer into the string passed in.
107 Accepts Unix (/-separated) paths on all systems,
108 DOS and VMS paths on those systems. */
113 const char *s
= fname
;
115 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
116 if (ISALPHA (s
[0]) && s
[1] == ':') s
+= 2;
117 if ((p
= strrchr (s
, '\\'))) s
= p
+ 1;
119 if ((p
= strrchr (s
, ':'))) s
= p
+ 1; /* Skip device. */
120 if ((p
= strrchr (s
, ']'))) s
= p
+ 1; /* Skip directory. */
121 if ((p
= strrchr (s
, '>'))) s
= p
+ 1; /* Skip alternate (int'n'l) dir. */
123 if ((p
= strrchr (s
, '/'))) s
= p
+ 1;
127 /* Public routines. */
132 struct deps
*d
= (struct deps
*) xmalloc (sizeof (struct deps
));
134 /* Allocate space for the vectors now. */
136 d
->targetv
= xmalloc (2 * sizeof (const char *));
137 d
->depv
= xmalloc (8 * sizeof (const char *));
152 for (i
= 0; i
< d
->ntargets
; i
++)
153 free ((PTR
) d
->targetv
[i
]);
154 for (i
= 0; i
< d
->ndeps
; i
++)
155 free ((PTR
) d
->depv
[i
]);
163 deps_add_target (d
, t
)
167 t
= munge (t
); /* Also makes permanent copy. */
169 if (d
->ntargets
== d
->targets_size
)
171 d
->targets_size
*= 2;
172 d
->targetv
= xrealloc (d
->targetv
,
173 d
->targets_size
* sizeof (const char *));
175 d
->targetv
[d
->ntargets
++] = t
;
179 deps_calc_target (d
, t
)
183 const char *o
, *suffix
;
186 o
= alloca (strlen (t
) + 8);
189 suffix
= strrchr (o
, '.');
191 strcpy (suffix
, OBJECT_SUFFIX
);
193 strcat (o
, OBJECT_SUFFIX
);
195 deps_add_target (d
, o
);
203 t
= munge (t
); /* Also makes permanent copy. */
205 if (d
->ndeps
== d
->deps_size
)
208 d
->depv
= xrealloc (d
->depv
, d
->deps_size
* sizeof (const char *));
210 d
->depv
[d
->ndeps
++] = t
;
214 deps_write (d
, fp
, colmax
)
215 const struct deps
*d
;
219 unsigned int size
, i
, column
;
222 if (colmax
&& colmax
< 34)
225 for (i
= 0; i
< d
->ntargets
; i
++)
227 size
= strlen (d
->targetv
[i
]);
229 if (colmax
&& column
> colmax
)
231 fputs (" \\\n ", fp
);
239 fputs (d
->targetv
[i
], fp
);
246 for (i
= 0; i
< d
->ndeps
; i
++)
248 size
= strlen (d
->depv
[i
]);
250 if (colmax
&& column
> colmax
)
252 fputs (" \\\n ", fp
);
260 fputs (d
->depv
[i
], fp
);
266 deps_dummy_targets (d
, fp
)
267 const struct deps
*d
;
272 for (i
= 1; i
< d
->ndeps
; i
++)
274 fputs (d
->depv
[i
], fp
);