mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-20 19:50:00 +08:00
7ceb3598d8
* cppfiles.c (file_cleanup, _cpp_find_include_file, remap_filename, _cpp_read_include_file, actual_directory, hack_vms_include_specification): Replace bcopy(), index() etc calls. Add casts to some allocations. Make some variables pointers to const [unsigned] char. * cpphash.c (_cpp_install, macro_cleanup, collect_expansion, collect_formal_parameters): Similarly. * cppinit.c (struct pending_option, append_include_chain, cpp_options_init, cpp_reader_init, initialize_standard_includes, cpp_start_read, new_pending_define, handle_option): Similarly. * cpplib.c (cpp_define, copy_comment, do_define, do_include, do_undef, do_error, do_warning, do_pragma, do_pragma_once, do_pragma_implementation, detect_if_not_defined, do_ifdef, skip_if_group, cpp_get_token, parse_string, do_assert, do_unassert): Similarly. * cpplib.h (cpp_buffer, cpp_options): Update types. Update function prototypes. * mkdeps.c (deps_add_target, deps_add_dep): cast allocations. From-SVN: r32477
285 lines
6.2 KiB
C
285 lines
6.2 KiB
C
/* 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; filename <= q && *q == '\\'; 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 == '\\'; 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 ()
|
|
{
|
|
struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
|
|
|
|
/* Allocate space for the vectors now. */
|
|
|
|
d->targetv = (const char **) xmalloc (2 * sizeof (const char *));
|
|
d->depv = (const char **) 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 = (const char **) 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;
|
|
{
|
|
char *o, *suffix;
|
|
|
|
t = base_name (t);
|
|
o = (char *) 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 = (const char **)
|
|
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;
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 1; i < d->ndeps; i++)
|
|
{
|
|
fputs (d->depv[i], fp);
|
|
putc (':', fp);
|
|
putc ('\n', fp);
|
|
}
|
|
}
|