OSDN Git Service

* builtins.c (built_in_class_names, built_in_names): Constify a
[pf3gnuchains/gcc-fork.git] / gcc / mkdeps.c
1 /* Dependency generator for Makefile fragments.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3    Contributed by Zack Weinberg, Mar 2000
4
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.
9
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.
14
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.
18
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!  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "mkdeps.h"
26
27 static const char *munge        PARAMS ((const char *));
28 static const char *base_name    PARAMS ((const char *));
29
30 #ifndef OBJECT_SUFFIX
31 # define OBJECT_SUFFIX ".o"
32 #endif
33
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.)  */
40    
41 static const char *
42 munge (filename)
43      const char *filename;
44 {
45   int len;
46   const char *p, *q;
47   char *dst, *buffer;
48
49   for (p = filename, len = 0; *p; p++, len++)
50     {
51       switch (*p)
52         {
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; q < filename && q[-1] == '\\';  q--)
62             len++;
63           len++;
64           break;
65
66         case '$':
67           /* '$' is quoted by doubling it. This can mishandle things
68              like "$(" but there's no easy fix.  */
69           len++;
70           break;
71         }
72     }
73
74   /* Now we know how big to make the buffer.  */
75   buffer = malloc (len + 1);
76
77   for (p = filename, dst = buffer; *p; p++, dst++)
78     {
79       switch (*p)
80         {
81         case ' ':
82         case '\t':
83           for (q = p - 1; filename < q && q[-1] == '\\';  q--)
84             *dst++ = '\\';
85           *dst++ = '\\';
86           break;
87
88         case '$':
89           *dst++ = '$';
90           break;
91
92         default:
93           /* nothing */;
94         }
95       *dst = *p;
96     }
97
98   *dst = '\0';
99   return buffer;
100 }
101
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.  */
109 static const char *
110 base_name (fname)
111      const char *fname;
112 {
113   const char *s = fname;
114   const char *p;
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;
118 #elif defined VMS
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.  */
122 #endif
123   if ((p = strrchr (s, '/'))) s = p + 1;
124   return s;
125 }
126
127 /* Public routines.  */
128
129 struct deps *
130 deps_init ()
131 {
132   struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
133
134   /* Allocate space for the vectors now.  */
135
136   d->targetv = xmalloc (2 * sizeof (const char *));
137   d->depv = xmalloc (8 * sizeof (const char *));
138
139   d->ntargets = 0;
140   d->targets_size = 2;
141   d->ndeps = 0;
142   d->deps_size = 8;
143
144   return d;
145 }
146
147 void
148 deps_free (d)
149      struct deps *d;
150 {
151   unsigned int i;
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]);
156
157   free (d->targetv);
158   free (d->depv);
159   free (d);
160 }
161
162 void
163 deps_add_target (d, t)
164      struct deps *d;
165      const char *t;
166 {
167   t = munge (t);  /* Also makes permanent copy.  */
168
169   if (d->ntargets == d->targets_size)
170     {
171       d->targets_size *= 2;
172       d->targetv = xrealloc (d->targetv,
173                              d->targets_size * sizeof (const char *));
174     }
175   d->targetv[d->ntargets++] = t;
176 }
177
178 void
179 deps_calc_target (d, t)
180      struct deps *d;
181      const char *t;
182 {
183   char *o, *suffix;
184
185   t = base_name (t);
186   o = alloca (strlen (t) + 8);
187
188   strcpy (o, t);
189   suffix = strrchr (o, '.');
190   if (suffix)
191     strcpy (suffix, OBJECT_SUFFIX);
192   else
193     strcat (o, OBJECT_SUFFIX);
194
195   deps_add_target (d, o);
196 }
197
198 void
199 deps_add_dep (d, t)
200      struct deps *d;
201      const char *t;
202 {
203   t = munge (t);  /* Also makes permanent copy.  */
204
205   if (d->ndeps == d->deps_size)
206     {
207       d->deps_size *= 2;
208       d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *));
209     }
210   d->depv[d->ndeps++] = t;
211 }
212
213 void
214 deps_write (d, fp, colmax)
215      const struct deps *d;
216      FILE *fp;
217      unsigned int colmax;
218 {
219   unsigned int size, i, column;
220
221   column = 0;
222   if (colmax && colmax < 34)
223     colmax = 34;
224
225   for (i = 0; i < d->ntargets; i++)
226     {
227       size = strlen (d->targetv[i]);
228       column += size;
229       if (colmax && column > colmax)
230         {
231           fputs (" \\\n ", fp);
232           column = 1 + size;
233         }
234       if (i)
235         {
236           putc (' ', fp);
237           column++;
238         }
239       fputs (d->targetv[i], fp);
240     }
241
242   putc (':', fp);
243   putc (' ', fp);
244   column += 2;
245
246   for (i = 0; i < d->ndeps; i++)
247     {
248       size = strlen (d->depv[i]);
249       column += size;
250       if (colmax && column > colmax)
251         {
252           fputs (" \\\n ", fp);
253           column = 1 + size;
254         }
255       if (i)
256         {
257           putc (' ', fp);
258           column++;
259         }
260       fputs (d->depv[i], fp);
261     }
262   putc ('\n', fp);
263 }
264   
265 void
266 deps_dummy_targets (d, fp)
267      const struct deps *d;
268      FILE *fp;
269 {
270   int i;
271
272   for (i = 1; i < d->ndeps; i++)
273     {
274       fputs (d->depv[i], fp);
275       putc (':', fp);
276       putc ('\n', fp);
277     }
278 }