diff options
author | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-03-04 19:42:04 +0000 |
---|---|---|
committer | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-03-04 19:42:04 +0000 |
commit | 62adb1fe3bb6c8175d557d5e74e1b63cb03d3623 (patch) | |
tree | b5fe0ea6f7acb88432c113e0e8949eba769d06b3 /gcc/mkdeps.c | |
parent | 85b5244c3c06d63def55f498b9de8f76f938f390 (diff) | |
download | gcc-62adb1fe3bb6c8175d557d5e74e1b63cb03d3623.tar.gz |
* mkdeps.c, mkdeps.h: New files.
* po/POTFILES.in: Add them.
* Makefile.in (LIBCPP_OBJS): Add mkdeps.o.
(cpplib.o, cppinit.o): Depend on mkdeps.h.
(mkdeps.o): New target.
* cppfiles.c: Delete deps_output.
* cppinit.c: Include mkdeps.h. Delete known_suffixes,
OBJECT_SUFFIX, and base_name.
(cpp_cleanup): Use deps_free. Free ihash->name when clearing
the include hash.
(initialize_dependency_output): Use deps_init,
deps_add_target, deps_calc_target, and deps_add_dep. Remove
all the unnecessary string bashing.
(cpp_finish): Use deps_write. Remove an unnecessary nesting
level.
* cpplib.c (do_include): Use deps_add_dep.
* cpplib.h (struct cpp_reader): Replace deps_buffer,
deps_allocated_size, deps_size, deps_column members with
single pointer to a struct deps. Delete prototype of
deps_output.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32329 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/mkdeps.c')
-rw-r--r-- | gcc/mkdeps.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/gcc/mkdeps.c b/gcc/mkdeps.c new file mode 100644 index 00000000000..43501ca365f --- /dev/null +++ b/gcc/mkdeps.c @@ -0,0 +1,278 @@ +/* Dependency generator for Makefile fragments. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Zack Weinberg, Mar 2000 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +#include "config.h" +#include "system.h" +#include "mkdeps.h" + +static const char *munge PARAMS ((const char *)); +static const char *base_name PARAMS ((const char *)); + +#ifndef OBJECT_SUFFIX +# define OBJECT_SUFFIX ".o" +#endif + +/* Given a filename, quote characters in that filename which are + significant to Make. Note that it's not possible to quote all such + characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are + not properly handled. It isn't possible to get this right in any + current version of Make. (??? Still true? Old comment referred to + 3.76.1.) */ + +static const char * +munge (filename) + const char *filename; +{ + int len; + const char *p, *q; + char *dst, *buffer; + + for (p = filename, len = 0; *p; p++, len++) + { + switch (*p) + { + case ' ': + case '\t': + /* GNU make uses a weird quoting scheme for white space. + A space or tab preceded by 2N+1 backslashes represents + N backslashes followed by space; a space or tab + preceded by 2N backslashes represents N backslashes at + the end of a file name; and backslashes in other + contexts should not be doubled. */ + for (q = p - 1; q < filename && q[-1] == '\\'; q--) + len++; + len++; + break; + + case '$': + /* '$' is quoted by doubling it. This can mishandle things + like "$(" but there's no easy fix. */ + len++; + break; + } + } + + /* Now we know how big to make the buffer. */ + buffer = malloc (len + 1); + + for (p = filename, dst = buffer; *p; p++, dst++) + { + switch (*p) + { + case ' ': + case '\t': + for (q = p - 1; filename < q && q[-1] == '\\'; q--) + *dst++ = '\\'; + *dst++ = '\\'; + break; + + case '$': + *dst++ = '$'; + break; + + default: + /* nothing */; + } + *dst = *p; + } + + *dst = '\0'; + return buffer; +} + +/* Given a pathname, calculate the non-directory part. This always + knows how to handle Unix-style pathnames, and understands VMS and + DOS paths on those systems. */ +/* Find the base name of a (partial) pathname FNAME. + Returns a pointer into the string passed in. + Accepts Unix (/-separated) paths on all systems, + DOS and VMS paths on those systems. */ +static const char * +base_name (fname) + const char *fname; +{ + const char *s = fname; + const char *p; +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (ISALPHA (s[0]) && s[1] == ':') s += 2; + if ((p = strrchr (s, '\\'))) s = p + 1; +#elif defined VMS + if ((p = strrchr (s, ':'))) s = p + 1; /* Skip device. */ + if ((p = strrchr (s, ']'))) s = p + 1; /* Skip directory. */ + if ((p = strrchr (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */ +#endif + if ((p = strrchr (s, '/'))) s = p + 1; + return s; +} + +/* Public routines. */ + +struct deps * +deps_init (void) +{ + struct deps *d = (struct deps *) xmalloc (sizeof (struct deps)); + + /* Allocate space for the vectors now. */ + + d->targetv = xmalloc (2 * sizeof (const char *)); + d->depv = xmalloc (8 * sizeof (const char *)); + + d->ntargets = 0; + d->targets_size = 2; + d->ndeps = 0; + d->deps_size = 8; + + return d; +} + +void +deps_free (d) + struct deps *d; +{ + unsigned int i; + for (i = 0; i < d->ntargets; i++) + free ((PTR) d->targetv[i]); + for (i = 0; i < d->ndeps; i++) + free ((PTR) d->depv[i]); + + free (d->targetv); + free (d->depv); + free (d); +} + +void +deps_add_target (d, t) + struct deps *d; + const char *t; +{ + t = munge (t); /* Also makes permanent copy. */ + + if (d->ntargets == d->targets_size) + { + d->targets_size *= 2; + d->targetv = xrealloc (d->targetv, + d->targets_size * sizeof (const char *)); + } + d->targetv[d->ntargets++] = t; +} + +void +deps_calc_target (d, t) + struct deps *d; + const char *t; +{ + const char *o, *suffix; + + t = base_name (t); + o = alloca (strlen (t) + 8); + + strcpy (o, t); + suffix = strrchr (o, '.'); + if (suffix) + strcpy (suffix, OBJECT_SUFFIX); + else + strcat (o, OBJECT_SUFFIX); + + deps_add_target (d, o); +} + +void +deps_add_dep (d, t) + struct deps *d; + const char *t; +{ + t = munge (t); /* Also makes permanent copy. */ + + if (d->ndeps == d->deps_size) + { + d->deps_size *= 2; + d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *)); + } + d->depv[d->ndeps++] = t; +} + +void +deps_write (d, fp, colmax) + const struct deps *d; + FILE *fp; + unsigned int colmax; +{ + unsigned int size, i, column; + + column = 0; + if (colmax && colmax < 34) + colmax = 34; + + for (i = 0; i < d->ntargets; i++) + { + size = strlen (d->targetv[i]); + column += size; + if (colmax && column > colmax) + { + fputs (" \\\n ", fp); + column = 1 + size; + } + if (i) + { + putc (' ', fp); + column++; + } + fputs (d->targetv[i], fp); + } + + putc (':', fp); + putc (' ', fp); + column += 2; + + for (i = 0; i < d->ndeps; i++) + { + size = strlen (d->depv[i]); + column += size; + if (colmax && column > colmax) + { + fputs (" \\\n ", fp); + column = 1 + size; + } + if (i) + { + putc (' ', fp); + column++; + } + fputs (d->depv[i], fp); + } + putc ('\n', fp); +} + +void +deps_dummy_targets (d, fp) + const struct deps *d; + FILE *fp; +{ + int i; + + for (i = 1; i < d->ndeps; i++) + { + fputs (d->depv[i], fp); + putc (':', fp); + putc ('\n', fp); + } +} |