OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libcpp/] [mkdeps.c] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 jlechner
/* Dependency generator for Makefile fragments.
2
   Copyright (C) 2000, 2001, 2003 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
/* Keep this structure local to this file, so clients don't find it
28
   easy to start making assumptions.  */
29
struct deps
30
{
31
  const char **targetv;
32
  unsigned int ntargets;        /* number of slots actually occupied */
33
  unsigned int targets_size;    /* amt of allocated space - in words */
34
 
35
  const char **depv;
36
  unsigned int ndeps;
37
  unsigned int deps_size;
38
 
39
  const char **vpathv;
40
  size_t *vpathlv;
41
  unsigned int nvpaths;
42
  unsigned int vpaths_size;
43
};
44
 
45
static const char *munge (const char *);
46
 
47
/* Given a filename, quote characters in that filename which are
48
   significant to Make.  Note that it's not possible to quote all such
49
   characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
50
   not properly handled.  It isn't possible to get this right in any
51
   current version of Make.  (??? Still true?  Old comment referred to
52
   3.76.1.)  */
53
 
54
static const char *
55
munge (const char *filename)
56
{
57
  int len;
58
  const char *p, *q;
59
  char *dst, *buffer;
60
 
61
  for (p = filename, len = 0; *p; p++, len++)
62
    {
63
      switch (*p)
64
        {
65
        case ' ':
66
        case '\t':
67
          /* GNU make uses a weird quoting scheme for white space.
68
             A space or tab preceded by 2N+1 backslashes represents
69
             N backslashes followed by space; a space or tab
70
             preceded by 2N backslashes represents N backslashes at
71
             the end of a file name; and backslashes in other
72
             contexts should not be doubled.  */
73
          for (q = p - 1; filename <= q && *q == '\\';  q--)
74
            len++;
75
          len++;
76
          break;
77
 
78
        case '$':
79
          /* '$' is quoted by doubling it.  */
80
          len++;
81
          break;
82
        }
83
    }
84
 
85
  /* Now we know how big to make the buffer.  */
86
  buffer = XNEWVEC (char, len + 1);
87
 
88
  for (p = filename, dst = buffer; *p; p++, dst++)
89
    {
90
      switch (*p)
91
        {
92
        case ' ':
93
        case '\t':
94
          for (q = p - 1; filename <= q && *q == '\\';  q--)
95
            *dst++ = '\\';
96
          *dst++ = '\\';
97
          break;
98
 
99
        case '$':
100
          *dst++ = '$';
101
          break;
102
 
103
        default:
104
          /* nothing */;
105
        }
106
      *dst = *p;
107
    }
108
 
109
  *dst = '\0';
110
  return buffer;
111
}
112
 
113
/* If T begins with any of the partial pathnames listed in d->vpathv,
114
   then advance T to point beyond that pathname.  */
115
static const char *
116
apply_vpath (struct deps *d, const char *t)
117
{
118
  if (d->vpathv)
119
    {
120
      unsigned int i;
121
      for (i = 0; i < d->nvpaths; i++)
122
        {
123
          if (!strncmp (d->vpathv[i], t, d->vpathlv[i]))
124
            {
125
              const char *p = t + d->vpathlv[i];
126
              if (!IS_DIR_SEPARATOR (*p))
127
                goto not_this_one;
128
 
129
              /* Do not simplify $(vpath)/../whatever.  ??? Might not
130
                 be necessary. */
131
              if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
132
                goto not_this_one;
133
 
134
              /* found a match */
135
              t = t + d->vpathlv[i] + 1;
136
              break;
137
            }
138
        not_this_one:;
139
        }
140
    }
141
 
142
  /* Remove leading ./ in any case.  */
143
  while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
144
    t += 2;
145
 
146
  return t;
147
}
148
 
149
/* Public routines.  */
150
 
151
struct deps *
152
deps_init (void)
153
{
154
  return XCNEW (struct deps);
155
}
156
 
157
void
158
deps_free (struct deps *d)
159
{
160
  unsigned int i;
161
 
162
  if (d->targetv)
163
    {
164
      for (i = 0; i < d->ntargets; i++)
165
        free ((void *) d->targetv[i]);
166
      free (d->targetv);
167
    }
168
 
169
  if (d->depv)
170
    {
171
      for (i = 0; i < d->ndeps; i++)
172
        free ((void *) d->depv[i]);
173
      free (d->depv);
174
    }
175
 
176
  if (d->vpathv)
177
    {
178
      for (i = 0; i < d->nvpaths; i++)
179
        free ((void *) d->vpathv[i]);
180
      free (d->vpathv);
181
      free (d->vpathlv);
182
    }
183
 
184
  free (d);
185
}
186
 
187
/* Adds a target T.  We make a copy, so it need not be a permanent
188
   string.  QUOTE is true if the string should be quoted.  */
189
void
190
deps_add_target (struct deps *d, const char *t, int quote)
191
{
192
  if (d->ntargets == d->targets_size)
193
    {
194
      d->targets_size = d->targets_size * 2 + 4;
195
      d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
196
    }
197
 
198
  t = apply_vpath (d, t);
199
  if (quote)
200
    t = munge (t);  /* Also makes permanent copy.  */
201
  else
202
    t = xstrdup (t);
203
 
204
  d->targetv[d->ntargets++] = t;
205
}
206
 
207
/* Sets the default target if none has been given already.  An empty
208
   string as the default target in interpreted as stdin.  The string
209
   is quoted for MAKE.  */
210
void
211
deps_add_default_target (struct deps *d, const char *tgt)
212
{
213
  /* Only if we have no targets.  */
214
  if (d->ntargets)
215
    return;
216
 
217
  if (tgt[0] == '\0')
218
    deps_add_target (d, "-", 1);
219
  else
220
    {
221
#ifndef TARGET_OBJECT_SUFFIX
222
# define TARGET_OBJECT_SUFFIX ".o"
223
#endif
224
      const char *start = lbasename (tgt);
225
      char *o = (char *) alloca (strlen (start)
226
                                 + strlen (TARGET_OBJECT_SUFFIX) + 1);
227
      char *suffix;
228
 
229
      strcpy (o, start);
230
 
231
      suffix = strrchr (o, '.');
232
      if (!suffix)
233
        suffix = o + strlen (o);
234
      strcpy (suffix, TARGET_OBJECT_SUFFIX);
235
 
236
      deps_add_target (d, o, 1);
237
    }
238
}
239
 
240
void
241
deps_add_dep (struct deps *d, const char *t)
242
{
243
  t = munge (apply_vpath (d, t));  /* Also makes permanent copy.  */
244
 
245
  if (d->ndeps == d->deps_size)
246
    {
247
      d->deps_size = d->deps_size * 2 + 8;
248
      d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
249
    }
250
  d->depv[d->ndeps++] = t;
251
}
252
 
253
void
254
deps_add_vpath (struct deps *d, const char *vpath)
255
{
256
  const char *elem, *p;
257
  char *copy;
258
  size_t len;
259
 
260
  for (elem = vpath; *elem; elem = p)
261
    {
262
      for (p = elem; *p && *p != ':'; p++);
263
      len = p - elem;
264
      copy = XNEWVEC (char, len + 1);
265
      memcpy (copy, elem, len);
266
      copy[len] = '\0';
267
      if (*p == ':')
268
        p++;
269
 
270
      if (d->nvpaths == d->vpaths_size)
271
        {
272
          d->vpaths_size = d->vpaths_size * 2 + 8;
273
          d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
274
          d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
275
        }
276
      d->vpathv[d->nvpaths] = copy;
277
      d->vpathlv[d->nvpaths] = len;
278
      d->nvpaths++;
279
    }
280
}
281
 
282
void
283
deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
284
{
285
  unsigned int size, i, column;
286
 
287
  column = 0;
288
  if (colmax && colmax < 34)
289
    colmax = 34;
290
 
291
  for (i = 0; i < d->ntargets; i++)
292
    {
293
      size = strlen (d->targetv[i]);
294
      column += size;
295
      if (colmax && column > colmax)
296
        {
297
          fputs (" \\\n ", fp);
298
          column = 1 + size;
299
        }
300
      if (i)
301
        {
302
          putc (' ', fp);
303
          column++;
304
        }
305
      fputs (d->targetv[i], fp);
306
    }
307
 
308
  putc (':', fp);
309
  putc (' ', fp);
310
  column += 2;
311
 
312
  for (i = 0; i < d->ndeps; i++)
313
    {
314
      size = strlen (d->depv[i]);
315
      column += size;
316
      if (colmax && column > colmax)
317
        {
318
          fputs (" \\\n ", fp);
319
          column = 1 + size;
320
        }
321
      if (i)
322
        {
323
          putc (' ', fp);
324
          column++;
325
        }
326
      fputs (d->depv[i], fp);
327
    }
328
  putc ('\n', fp);
329
}
330
 
331
void
332
deps_phony_targets (const struct deps *d, FILE *fp)
333
{
334
  unsigned int i;
335
 
336
  for (i = 1; i < d->ndeps; i++)
337
    {
338
      putc ('\n', fp);
339
      fputs (d->depv[i], fp);
340
      putc (':', fp);
341
      putc ('\n', fp);
342
    }
343
}
344
 
345
/* Write out a deps buffer to a file, in a form that can be read back
346
   with deps_restore.  Returns nonzero on error, in which case the
347
   error number will be in errno.  */
348
 
349
int
350
deps_save (struct deps *deps, FILE *f)
351
{
352
  unsigned int i;
353
 
354
  /* The cppreader structure contains makefile dependences.  Write out this
355
     structure.  */
356
 
357
  /* The number of dependences.  */
358
  if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
359
      return -1;
360
  /* The length of each dependence followed by the string.  */
361
  for (i = 0; i < deps->ndeps; i++)
362
    {
363
      size_t num_to_write = strlen (deps->depv[i]);
364
      if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
365
          return -1;
366
      if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
367
          return -1;
368
    }
369
 
370
  return 0;
371
}
372
 
373
/* Read back dependency information written with deps_save into
374
   the deps buffer.  The third argument may be NULL, in which case
375
   the dependency information is just skipped, or it may be a filename,
376
   in which case that filename is skipped.  */
377
 
378
int
379
deps_restore (struct deps *deps, FILE *fd, const char *self)
380
{
381
  unsigned int i, count;
382
  size_t num_to_read;
383
  size_t buf_size = 512;
384
  char *buf = XNEWVEC (char, buf_size);
385
 
386
  /* Number of dependences.  */
387
  if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
388
    return -1;
389
 
390
  /* The length of each dependence string, followed by the string.  */
391
  for (i = 0; i < count; i++)
392
    {
393
      /* Read in # bytes in string.  */
394
      if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
395
        return -1;
396
      if (buf_size < num_to_read + 1)
397
        {
398
          buf_size = num_to_read + 1 + 127;
399
          buf = XRESIZEVEC (char, buf, buf_size);
400
        }
401
      if (fread (buf, 1, num_to_read, fd) != num_to_read)
402
        return -1;
403
      buf[num_to_read] = '\0';
404
 
405
      /* Generate makefile dependencies from .pch if -nopch-deps.  */
406
      if (self != NULL && strcmp (buf, self) != 0)
407
        deps_add_dep (deps, buf);
408
    }
409
 
410
  free (buf);
411
  return 0;
412
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.