OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [libcpp/] [mkdeps.c] - Blame information for rev 168

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Dependency generator for Makefile fragments.
2
   Copyright (C) 2000, 2001, 2003, 2007 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
    {
145
      t += 2;
146
      /* If we removed a leading ./, then also remove any /s after the
147
         first.  */
148
      while (IS_DIR_SEPARATOR (t[0]))
149
        ++t;
150
    }
151
 
152
  return t;
153
}
154
 
155
/* Public routines.  */
156
 
157
struct deps *
158
deps_init (void)
159
{
160
  return XCNEW (struct deps);
161
}
162
 
163
void
164
deps_free (struct deps *d)
165
{
166
  unsigned int i;
167
 
168
  if (d->targetv)
169
    {
170
      for (i = 0; i < d->ntargets; i++)
171
        free ((void *) d->targetv[i]);
172
      free (d->targetv);
173
    }
174
 
175
  if (d->depv)
176
    {
177
      for (i = 0; i < d->ndeps; i++)
178
        free ((void *) d->depv[i]);
179
      free (d->depv);
180
    }
181
 
182
  if (d->vpathv)
183
    {
184
      for (i = 0; i < d->nvpaths; i++)
185
        free ((void *) d->vpathv[i]);
186
      free (d->vpathv);
187
      free (d->vpathlv);
188
    }
189
 
190
  free (d);
191
}
192
 
193
/* Adds a target T.  We make a copy, so it need not be a permanent
194
   string.  QUOTE is true if the string should be quoted.  */
195
void
196
deps_add_target (struct deps *d, const char *t, int quote)
197
{
198
  if (d->ntargets == d->targets_size)
199
    {
200
      d->targets_size = d->targets_size * 2 + 4;
201
      d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
202
    }
203
 
204
  t = apply_vpath (d, t);
205
  if (quote)
206
    t = munge (t);  /* Also makes permanent copy.  */
207
  else
208
    t = xstrdup (t);
209
 
210
  d->targetv[d->ntargets++] = t;
211
}
212
 
213
/* Sets the default target if none has been given already.  An empty
214
   string as the default target in interpreted as stdin.  The string
215
   is quoted for MAKE.  */
216
void
217
deps_add_default_target (struct deps *d, const char *tgt)
218
{
219
  /* Only if we have no targets.  */
220
  if (d->ntargets)
221
    return;
222
 
223
  if (tgt[0] == '\0')
224
    deps_add_target (d, "-", 1);
225
  else
226
    {
227
#ifndef TARGET_OBJECT_SUFFIX
228
# define TARGET_OBJECT_SUFFIX ".o"
229
#endif
230
      const char *start = lbasename (tgt);
231
      char *o = (char *) alloca (strlen (start)
232
                                 + strlen (TARGET_OBJECT_SUFFIX) + 1);
233
      char *suffix;
234
 
235
      strcpy (o, start);
236
 
237
      suffix = strrchr (o, '.');
238
      if (!suffix)
239
        suffix = o + strlen (o);
240
      strcpy (suffix, TARGET_OBJECT_SUFFIX);
241
 
242
      deps_add_target (d, o, 1);
243
    }
244
}
245
 
246
void
247
deps_add_dep (struct deps *d, const char *t)
248
{
249
  t = munge (apply_vpath (d, t));  /* Also makes permanent copy.  */
250
 
251
  if (d->ndeps == d->deps_size)
252
    {
253
      d->deps_size = d->deps_size * 2 + 8;
254
      d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
255
    }
256
  d->depv[d->ndeps++] = t;
257
}
258
 
259
void
260
deps_add_vpath (struct deps *d, const char *vpath)
261
{
262
  const char *elem, *p;
263
  char *copy;
264
  size_t len;
265
 
266
  for (elem = vpath; *elem; elem = p)
267
    {
268
      for (p = elem; *p && *p != ':'; p++);
269
      len = p - elem;
270
      copy = XNEWVEC (char, len + 1);
271
      memcpy (copy, elem, len);
272
      copy[len] = '\0';
273
      if (*p == ':')
274
        p++;
275
 
276
      if (d->nvpaths == d->vpaths_size)
277
        {
278
          d->vpaths_size = d->vpaths_size * 2 + 8;
279
          d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
280
          d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
281
        }
282
      d->vpathv[d->nvpaths] = copy;
283
      d->vpathlv[d->nvpaths] = len;
284
      d->nvpaths++;
285
    }
286
}
287
 
288
void
289
deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
290
{
291
  unsigned int size, i, column;
292
 
293
  column = 0;
294
  if (colmax && colmax < 34)
295
    colmax = 34;
296
 
297
  for (i = 0; i < d->ntargets; i++)
298
    {
299
      size = strlen (d->targetv[i]);
300
      column += size;
301
      if (colmax && column > colmax)
302
        {
303
          fputs (" \\\n ", fp);
304
          column = 1 + size;
305
        }
306
      if (i)
307
        {
308
          putc (' ', fp);
309
          column++;
310
        }
311
      fputs (d->targetv[i], fp);
312
    }
313
 
314
  putc (':', fp);
315
  putc (' ', fp);
316
  column += 2;
317
 
318
  for (i = 0; i < d->ndeps; i++)
319
    {
320
      size = strlen (d->depv[i]);
321
      column += size;
322
      if (colmax && column > colmax)
323
        {
324
          fputs (" \\\n ", fp);
325
          column = 1 + size;
326
        }
327
      if (i)
328
        {
329
          putc (' ', fp);
330
          column++;
331
        }
332
      fputs (d->depv[i], fp);
333
    }
334
  putc ('\n', fp);
335
}
336
 
337
void
338
deps_phony_targets (const struct deps *d, FILE *fp)
339
{
340
  unsigned int i;
341
 
342
  for (i = 1; i < d->ndeps; i++)
343
    {
344
      putc ('\n', fp);
345
      fputs (d->depv[i], fp);
346
      putc (':', fp);
347
      putc ('\n', fp);
348
    }
349
}
350
 
351
/* Write out a deps buffer to a file, in a form that can be read back
352
   with deps_restore.  Returns nonzero on error, in which case the
353
   error number will be in errno.  */
354
 
355
int
356
deps_save (struct deps *deps, FILE *f)
357
{
358
  unsigned int i;
359
 
360
  /* The cppreader structure contains makefile dependences.  Write out this
361
     structure.  */
362
 
363
  /* The number of dependences.  */
364
  if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
365
      return -1;
366
  /* The length of each dependence followed by the string.  */
367
  for (i = 0; i < deps->ndeps; i++)
368
    {
369
      size_t num_to_write = strlen (deps->depv[i]);
370
      if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
371
          return -1;
372
      if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
373
          return -1;
374
    }
375
 
376
  return 0;
377
}
378
 
379
/* Read back dependency information written with deps_save into
380
   the deps buffer.  The third argument may be NULL, in which case
381
   the dependency information is just skipped, or it may be a filename,
382
   in which case that filename is skipped.  */
383
 
384
int
385
deps_restore (struct deps *deps, FILE *fd, const char *self)
386
{
387
  unsigned int i, count;
388
  size_t num_to_read;
389
  size_t buf_size = 512;
390
  char *buf = XNEWVEC (char, buf_size);
391
 
392
  /* Number of dependences.  */
393
  if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
394
    return -1;
395
 
396
  /* The length of each dependence string, followed by the string.  */
397
  for (i = 0; i < count; i++)
398
    {
399
      /* Read in # bytes in string.  */
400
      if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
401
        return -1;
402
      if (buf_size < num_to_read + 1)
403
        {
404
          buf_size = num_to_read + 1 + 127;
405
          buf = XRESIZEVEC (char, buf, buf_size);
406
        }
407
      if (fread (buf, 1, num_to_read, fd) != num_to_read)
408
        return -1;
409
      buf[num_to_read] = '\0';
410
 
411
      /* Generate makefile dependencies from .pch if -nopch-deps.  */
412
      if (self != NULL && strcmp (buf, self) != 0)
413
        deps_add_dep (deps, buf);
414
    }
415
 
416
  free (buf);
417
  return 0;
418
}

powered by: WebSVN 2.1.0

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