* tm.texi (REGISTER_MOVE_COST): Add a mode argument.
[official-gcc.git] / gcc / mkdeps.c
blob66417d00fee9c9a162246ca2f32023d36ab08a79
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
8 later version.
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! */
23 #include "config.h"
24 #include "system.h"
25 #include "mkdeps.h"
27 static const char *munge PARAMS ((const char *));
28 static const char *base_name PARAMS ((const char *));
30 #ifndef OBJECT_SUFFIX
31 # define OBJECT_SUFFIX ".o"
32 #endif
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
39 3.76.1.) */
41 static const char *
42 munge (filename)
43 const char *filename;
45 int len;
46 const char *p, *q;
47 char *dst, *buffer;
49 for (p = filename, len = 0; *p; p++, len++)
51 switch (*p)
53 case ' ':
54 case '\t':
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; filename <= q && *q == '\\'; q--)
62 len++;
63 len++;
64 break;
66 case '$':
67 /* '$' is quoted by doubling it. This can mishandle things
68 like "$(" but there's no easy fix. */
69 len++;
70 break;
74 /* Now we know how big to make the buffer. */
75 buffer = xmalloc (len + 1);
77 for (p = filename, dst = buffer; *p; p++, dst++)
79 switch (*p)
81 case ' ':
82 case '\t':
83 for (q = p - 1; filename <= q && *q == '\\'; q--)
84 *dst++ = '\\';
85 *dst++ = '\\';
86 break;
88 case '$':
89 *dst++ = '$';
90 break;
92 default:
93 /* nothing */;
95 *dst = *p;
98 *dst = '\0';
99 return buffer;
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. */
106 /* Find the base name of a (partial) pathname FNAME.
107 Returns a pointer into the string passed in.
108 Accepts Unix (/-separated) paths on all systems,
109 DOS and VMS paths on those systems. */
111 static const char *
112 base_name (fname)
113 const char *fname;
115 const char *s = fname;
116 const char *p;
117 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
118 if (ISALPHA (s[0]) && s[1] == ':') s += 2;
119 if ((p = strrchr (s, '\\'))) s = p + 1;
120 #elif defined VMS
121 if ((p = strrchr (s, ':'))) s = p + 1; /* Skip device. */
122 if ((p = strrchr (s, ']'))) s = p + 1; /* Skip directory. */
123 if ((p = strrchr (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
124 #endif
125 if ((p = strrchr (s, '/'))) s = p + 1;
126 return s;
129 /* Public routines. */
131 struct deps *
132 deps_init ()
134 struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
136 /* Allocate space for the vectors now. */
138 d->targetv = (const char **) xmalloc (2 * sizeof (const char *));
139 d->depv = (const char **) xmalloc (8 * sizeof (const char *));
141 d->ntargets = 0;
142 d->targets_size = 2;
143 d->ndeps = 0;
144 d->deps_size = 8;
146 return d;
149 void
150 deps_free (d)
151 struct deps *d;
153 unsigned int i;
155 for (i = 0; i < d->ntargets; i++)
156 free ((PTR) d->targetv[i]);
158 for (i = 0; i < d->ndeps; i++)
159 free ((PTR) d->depv[i]);
161 free (d->targetv);
162 free (d->depv);
163 free (d);
166 void
167 deps_add_target (d, t)
168 struct deps *d;
169 const char *t;
171 t = munge (t); /* Also makes permanent copy. */
173 if (d->ntargets == d->targets_size)
175 d->targets_size *= 2;
176 d->targetv = (const char **) xrealloc (d->targetv,
177 d->targets_size * sizeof (const char *));
180 d->targetv[d->ntargets++] = t;
183 void
184 deps_calc_target (d, t)
185 struct deps *d;
186 const char *t;
188 char *o, *suffix;
190 t = base_name (t);
191 o = (char *) alloca (strlen (t) + 8);
193 strcpy (o, t);
194 suffix = strrchr (o, '.');
195 if (suffix)
196 strcpy (suffix, OBJECT_SUFFIX);
197 else
198 strcat (o, OBJECT_SUFFIX);
200 deps_add_target (d, o);
203 void
204 deps_add_dep (d, t)
205 struct deps *d;
206 const char *t;
208 t = munge (t); /* Also makes permanent copy. */
210 if (d->ndeps == d->deps_size)
212 d->deps_size *= 2;
213 d->depv = (const char **)
214 xrealloc (d->depv, d->deps_size * sizeof (const char *));
216 d->depv[d->ndeps++] = t;
219 void
220 deps_write (d, fp, colmax)
221 const struct deps *d;
222 FILE *fp;
223 unsigned int colmax;
225 unsigned int size, i, column;
227 column = 0;
228 if (colmax && colmax < 34)
229 colmax = 34;
231 for (i = 0; i < d->ntargets; i++)
233 size = strlen (d->targetv[i]);
234 column += size;
235 if (colmax && column > colmax)
237 fputs (" \\\n ", fp);
238 column = 1 + size;
240 if (i)
242 putc (' ', fp);
243 column++;
245 fputs (d->targetv[i], fp);
248 putc (':', fp);
249 putc (' ', fp);
250 column += 2;
252 for (i = 0; i < d->ndeps; i++)
254 size = strlen (d->depv[i]);
255 column += size;
256 if (colmax && column > colmax)
258 fputs (" \\\n ", fp);
259 column = 1 + size;
261 if (i)
263 putc (' ', fp);
264 column++;
266 fputs (d->depv[i], fp);
268 putc ('\n', fp);
271 void
272 deps_dummy_targets (d, fp)
273 const struct deps *d;
274 FILE *fp;
276 unsigned int i;
278 for (i = 1; i < d->ndeps; i++)
280 fputs (d->depv[i], fp);
281 putc (':', fp);
282 putc ('\n', fp);