aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog31
-rw-r--r--libcpp/Makefile.am3
-rw-r--r--libcpp/Makefile.in60
-rw-r--r--libcpp/aclocal.m44
-rw-r--r--libcpp/charset.c2
-rw-r--r--libcpp/directives.c43
-rw-r--r--libcpp/files.c79
-rw-r--r--libcpp/include/cpplib.h13
-rw-r--r--libcpp/include/mkdeps.h7
-rw-r--r--libcpp/include/symtab.h5
-rw-r--r--libcpp/init.c12
-rw-r--r--libcpp/internal.h4
-rw-r--r--libcpp/lex.c28
-rw-r--r--libcpp/macro.c6
-rw-r--r--libcpp/makedepend.c205
-rw-r--r--libcpp/mkdeps.c96
-rw-r--r--libcpp/symtab.c16
17 files changed, 503 insertions, 111 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 71a4495..4cd511b 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,34 @@
+2004-06-05 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.am: Add makedepend.
+ * Makefile.in, aclocal.m4: Regenerate.
+ * charset.c: Insert a space to avoid a warning.
+ * directives.c: Include mkdeps.h.
+ (_cpp_handle_directive): Reenable macro expander if appropriate.
+ (undefine_macros): Inline body of _cpp_free_definition for speed.
+ Do not call undef callback or _cpp_warn_if_unused_macro.
+ (cpp_get_deps): New interface.
+ * files.c (search_cache): Add pfile argument. Check for file
+ that would be found by "" or <> search here...
+ (_cpp_find_file): ...not here. Correct recorded start_dir of
+ files found by directory-of-current-file search that would be
+ found by "" or <> search.
+ * init.c (cpp_add_dependency_target): Delete.
+ * internal.h (struct lexer_state): Add discarding_output flag.
+ * lex.c (lex_identifier): Compute hash function while scanning.
+ * macro.c (cpp_scan_nooutput): Disable macro expansion outside
+ directives.
+ * makedepend.c: New file.
+ * mkdeps.c (struct deps): Add vpath vector.
+ (apply_vpath, deps_add_vpath): New function.
+ (deps_free): Free vpath vector.
+ (deps_add_dep, deps_add_target): Use apply_vpath.
+ * symtab.c (calc_hash): Use HT_HASHSTEP and HT_FINISH.
+ (ht_lookup_with_hash): New function.
+ * cpplib.h, mkdeps.h: Update prototypes.
+ * symtab.h: Update prototypes.
+ (HT_HASHSTEP, HT_FINISH): New macros.
+
2004-05-29 Geoffrey Keating <geoffk@apple.com>
* symtab.c (ht_create): Set entries_owned.
diff --git a/libcpp/Makefile.am b/libcpp/Makefile.am
index 4d9be51..57103bf 100644
--- a/libcpp/Makefile.am
+++ b/libcpp/Makefile.am
@@ -13,6 +13,9 @@ noinst_HEADERS = \
include/cpplib.h include/line-map.h include/mkdeps.h \
include/symtab.h internal.h system.h ucnid.h
+noinst_PROGRAMS = makedepend
+makedepend_LDADD = libcpp.a ../libiberty/libiberty.a
+
XGETTEXT = @XGETTEXT@
GMSGFMT = @GMSGFMT@
MSGMERGE = msgmerge
diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in
index 5df4f3e..3820a1b 100644
--- a/libcpp/Makefile.in
+++ b/libcpp/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# Makefile.in generated by automake 1.8.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -15,7 +15,8 @@
@SET_MAKE@
-SOURCES = $(libcpp_a_SOURCES)
+
+SOURCES = $(libcpp_a_SOURCES) makedepend.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -40,6 +41,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
+noinst_PROGRAMS = makedepend$(EXEEXT)
DIST_COMMON = $(am__configure_deps) $(noinst_HEADERS) \
$(srcdir)/../config.guess $(srcdir)/../config.sub \
$(srcdir)/../depcomp $(srcdir)/../install-sh \
@@ -57,9 +59,9 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
-LIBRARIES = $(noinst_LIBRARIES)
libcpp_a_AR = $(AR) $(ARFLAGS)
libcpp_a_LIBADD =
am_libcpp_a_OBJECTS = charset.$(OBJEXT) directives.$(OBJEXT) \
@@ -68,6 +70,10 @@ am_libcpp_a_OBJECTS = charset.$(OBJEXT) directives.$(OBJEXT) \
line-map.$(OBJEXT) macro.$(OBJEXT) mkdeps.$(OBJEXT) \
pch.$(OBJEXT) symtab.$(OBJEXT) traditional.$(OBJEXT)
libcpp_a_OBJECTS = $(am_libcpp_a_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+makedepend_SOURCES = makedepend.c
+makedepend_OBJECTS = makedepend.$(OBJEXT)
+makedepend_DEPENDENCIES = libcpp.a ../libiberty/libiberty.a
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -76,15 +82,15 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/expr.Po ./$(DEPDIR)/files.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/identifiers.Po ./$(DEPDIR)/init.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/lex.Po ./$(DEPDIR)/line-map.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/macro.Po ./$(DEPDIR)/mkdeps.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/pch.Po ./$(DEPDIR)/symtab.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/traditional.Po
+@AMDEP_TRUE@ ./$(DEPDIR)/macro.Po ./$(DEPDIR)/makedepend.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/mkdeps.Po ./$(DEPDIR)/pch.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/symtab.Po ./$(DEPDIR)/traditional.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libcpp_a_SOURCES)
-DIST_SOURCES = $(libcpp_a_SOURCES)
+SOURCES = $(libcpp_a_SOURCES) makedepend.c
+DIST_SOURCES = $(libcpp_a_SOURCES) makedepend.c
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
@@ -213,6 +219,7 @@ noinst_HEADERS = \
include/cpplib.h include/line-map.h include/mkdeps.h \
include/symtab.h internal.h system.h ucnid.h
+makedepend_LDADD = libcpp.a ../libiberty/libiberty.a
MSGMERGE = msgmerge
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -277,6 +284,12 @@ libcpp.a: $(libcpp_a_OBJECTS) $(libcpp_a_DEPENDENCIES)
$(libcpp_a_AR) libcpp.a $(libcpp_a_OBJECTS) $(libcpp_a_LIBADD)
$(RANLIB) libcpp.a
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+makedepend$(EXEEXT): $(makedepend_OBJECTS) $(makedepend_DEPENDENCIES)
+ @rm -f makedepend$(EXEEXT)
+ $(LINK) $(makedepend_LDFLAGS) $(makedepend_OBJECTS) $(makedepend_LDADD) $(LIBS)
+
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -293,6 +306,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/line-map.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/macro.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makedepend.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkdeps.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symtab.Po@am__quote@
@@ -336,7 +350,7 @@ TAGS: $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -z "$$unique" && unique=$$empty_fix; \
+ test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
@@ -492,7 +506,7 @@ distcleancheck: distclean
exit 1; } >&2
check-am: all-am
check: check-am
-all-am: Makefile $(LIBRARIES) $(HEADERS) config.h
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(HEADERS) config.h
installdirs:
install: install-am
install-exec: install-exec-am
@@ -520,7 +534,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \
+ mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -571,17 +586,18 @@ ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
- clean-generic clean-noinstLIBRARIES ctags dist dist-all \
- dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip distcheck \
- distclean distclean-compile distclean-generic distclean-hdr \
- distclean-tags distcleancheck distdir distuninstallcheck dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-data-local install-exec \
- install-exec-am install-info install-info-am install-man \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-info-am
+ clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \
+ dist dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ \
+ dist-zip distcheck distclean distclean-compile \
+ distclean-generic distclean-hdr distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-data-local install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-info-am
@ENABLE_NLS_TRUE@build-po: $(CATALOGS)
diff --git a/libcpp/aclocal.m4 b/libcpp/aclocal.m4
index 12cd2d0fe..0491339 100644
--- a/libcpp/aclocal.m4
+++ b/libcpp/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.8.4 -*- Autoconf -*-
+# generated automatically by aclocal 1.8.5 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
# Free Software Foundation, Inc.
@@ -989,7 +989,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
- [AM_AUTOMAKE_VERSION([1.8.4])])
+ [AM_AUTOMAKE_VERSION([1.8.5])])
# AM_AUX_DIR_EXPAND
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 45e2454..4de858a 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -1409,7 +1409,7 @@ _cpp_default_encoding (void)
- the appropriate Unicode byte-order mark (FE FF) to recognize
UTF16 and UCS4 (in both big-endian and little-endian flavors)
and UTF8
- - a "#i", "#d", "/*", "//", " #p" or "#p" (for #pragma) to
+ - a "#i", "#d", "/ *", "//", " #p" or "#p" (for #pragma) to
distinguish ASCII and EBCDIC.
- now we can parse something like "#pragma GCC encoding <xyz>
on the first line, or even Emacs/VIM's mode line tags (there's
diff --git a/libcpp/directives.c b/libcpp/directives.c
index f9ff2ce..5a6a342 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -23,6 +23,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "system.h"
#include "cpplib.h"
#include "internal.h"
+#include "mkdeps.h"
#include "obstack.h"
/* Chained list of answers to an assertion. */
@@ -336,8 +337,12 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
const directive *dir = 0;
const cpp_token *dname;
bool was_parsing_args = pfile->state.parsing_args;
+ bool was_discarding_output = pfile->state.discarding_output;
int skip = 1;
+ if (was_discarding_output)
+ pfile->state.prevent_expansion = 0;
+
if (was_parsing_args)
{
if (CPP_OPTION (pfile, pedantic))
@@ -432,6 +437,8 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
pfile->state.parsing_args = 2;
pfile->state.prevent_expansion = 1;
}
+ if (was_discarding_output)
+ pfile->state.prevent_expansion = 1;
return skip;
}
@@ -549,30 +556,13 @@ do_undef (cpp_reader *pfile)
/* Undefine a single macro/assertion/whatever. */
static int
-undefine_macros (cpp_reader *pfile, cpp_hashnode *h,
+undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h,
void *data_p ATTRIBUTE_UNUSED)
{
- switch (h->type)
- {
- case NT_VOID:
- break;
-
- case NT_MACRO:
- if (pfile->cb.undef)
- (*pfile->cb.undef) (pfile, pfile->directive_line, h);
-
- if (CPP_OPTION (pfile, warn_unused_macros))
- _cpp_warn_if_unused_macro (pfile, h, NULL);
-
- /* And fall through.... */
- case NT_ASSERTION:
- _cpp_free_definition (h);
- break;
-
- default:
- abort ();
- }
- h->flags &= ~NODE_POISONED;
+ /* Body of _cpp_free_definition inlined here for speed.
+ Macros and assertions no longer have anything to free. */
+ h->type = NT_VOID;
+ h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED);
return 1;
}
@@ -1913,6 +1903,15 @@ cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
pfile->cb = *cb;
}
+/* The dependencies structure. (Creates one if it hasn't already been.) */
+struct deps *
+cpp_get_deps (cpp_reader *pfile)
+{
+ if (!pfile->deps)
+ pfile->deps = deps_init ();
+ return pfile->deps;
+}
+
/* Push a new buffer on the buffer stack. Returns the new buffer; it
doesn't fail. It does not generate a file change call back; that
is the responsibility of the caller. */
diff --git a/libcpp/files.c b/libcpp/files.c
index 7d7b271..6a18d71 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -158,7 +158,8 @@ static struct cpp_dir *search_path_head (cpp_reader *, const char *fname,
int angle_brackets, enum include_type);
static const char *dir_name_of_file (_cpp_file *file);
static void open_file_failed (cpp_reader *pfile, _cpp_file *file);
-static struct file_hash_entry *search_cache (struct file_hash_entry *head,
+static struct file_hash_entry *search_cache (cpp_reader *pfile,
+ struct file_hash_entry *head,
const cpp_dir *start_dir);
static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
@@ -406,7 +407,7 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
INSERT);
/* First check the cache before we resort to memory allocation. */
- entry = search_cache (*hash_slot, start_dir);
+ entry = search_cache (pfile, *hash_slot, start_dir);
if (entry)
return entry->u.file;
@@ -435,17 +436,6 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
}
break;
}
-
- /* Only check the cache for the starting location (done above)
- and the quote and bracket chain heads because there are no
- other possible starting points for searches. */
- if (file->dir != pfile->bracket_include
- && file->dir != pfile->quote_include)
- continue;
-
- entry = search_cache (*hash_slot, file->dir);
- if (entry)
- break;
}
if (entry)
@@ -462,6 +452,33 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
pfile->all_files = file;
}
+ /* If this file was found in the directory-of-the-current-file,
+ check whether that directory is reachable via one of the normal
+ search paths. If so, we must record this entry as being
+ reachable that way, otherwise we will mistakenly reprocess this
+ file if it is included later from the normal search path. */
+ if (file->dir && start_dir->next == pfile->quote_include)
+ {
+ cpp_dir *d;
+ cpp_dir *proper_start_dir = pfile->quote_include;
+
+ for (d = proper_start_dir;; d = d->next)
+ {
+ if (d == pfile->bracket_include)
+ proper_start_dir = d;
+ if (d == 0)
+ {
+ proper_start_dir = 0;
+ break;
+ }
+ /* file->dir->name will have a trailing slash. */
+ if (!strncmp (d->name, file->dir->name, file->dir->len - 1))
+ break;
+ }
+ if (proper_start_dir)
+ start_dir = proper_start_dir;
+ }
+
/* Store this new result in the hash table. */
entry = new_file_hash_entry (pfile);
entry->next = *hash_slot;
@@ -821,12 +838,40 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file)
/* Search in the chain beginning at HEAD for a file whose search path
started at START_DIR != NULL. */
static struct file_hash_entry *
-search_cache (struct file_hash_entry *head, const cpp_dir *start_dir)
+search_cache (cpp_reader *pfile, struct file_hash_entry *head,
+ const cpp_dir *start_dir)
{
- while (head && head->start_dir != start_dir)
- head = head->next;
+ struct file_hash_entry *p;
+
+ /* Look for a file that was found from a search starting at the
+ given location. */
+ for (p = head; p; p = p->next)
+ if (p->start_dir == start_dir)
+ return p;
+
+ /* If the given location is for a search of the directory containing
+ the current file, check for a match starting at the base of the
+ quoted include chain. */
+ if (start_dir->next == pfile->quote_include)
+ {
+ start_dir = pfile->quote_include;
+ for (p = head; p; p = p->next)
+ if (p->start_dir == start_dir)
+ return p;
+ }
- return head;
+ /* If the given location is for a search from the base of the quoted
+ include chain, check for a match starting at the base of the
+ bracket include chain. */
+ if (start_dir == pfile->quote_include)
+ {
+ start_dir = pfile->bracket_include;
+ for (p = head; p; p = p->next)
+ if (p->start_dir == start_dir)
+ return p;
+ }
+
+ return 0;
}
/* Allocate a new _cpp_file structure. */
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 7f20104..cf701b5 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -538,23 +538,18 @@ extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *,
command line options). */
extern void cpp_set_lang (cpp_reader *, enum c_lang);
-/* Add a dependency TARGET. Quote it for "make" if QUOTE. Can be
- called any number of times before cpp_read_main_file(). If no
- targets have been added before cpp_read_main_file(), then the
- default target is used. */
-extern void cpp_add_dependency_target (cpp_reader *, const char *, int);
-
/* Set the include paths. */
extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int);
-/* Call these to get pointers to the options and callback structures
- for a given reader. These pointers are good until you call
- cpp_finish on that reader. You can either edit the callbacks
+/* Call these to get pointers to the options, callback, and deps
+ structures for a given reader. These pointers are good until you
+ call cpp_finish on that reader. You can either edit the callbacks
through the pointer returned from cpp_get_callbacks, or set them
with cpp_set_callbacks. */
extern cpp_options *cpp_get_options (cpp_reader *);
extern cpp_callbacks *cpp_get_callbacks (cpp_reader *);
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
+extern struct deps *cpp_get_deps (cpp_reader *);
/* This function reads the file, but does not start preprocessing. It
returns the name of the original file; this is the same as the
diff --git a/libcpp/include/mkdeps.h b/libcpp/include/mkdeps.h
index b5f9a05..56ffdaf 100644
--- a/libcpp/include/mkdeps.h
+++ b/libcpp/include/mkdeps.h
@@ -34,6 +34,13 @@ extern struct deps *deps_init (void);
/* Destroy a deps buffer. */
extern void deps_free (struct deps *);
+/* Add a set of "vpath" directories. The second argument is a colon-
+ separated list of pathnames, like you would set Make's VPATH
+ variable to. If a dependency or target name begins with any of
+ these pathnames (and the next path element is not "..") that
+ pathname is stripped off. */
+extern void deps_add_vpath (struct deps *, const char *);
+
/* Add a target (appears on left side of the colon) to the deps list. Takes
a boolean indicating whether to quote the target for MAKE. */
extern void deps_add_target (struct deps *, const char *, int);
diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h
index 85e285b..d11e4ef 100644
--- a/libcpp/include/symtab.h
+++ b/libcpp/include/symtab.h
@@ -71,6 +71,11 @@ extern void ht_destroy (hash_table *);
extern hashnode ht_lookup (hash_table *, const unsigned char *,
size_t, enum ht_lookup_option);
+extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *,
+ size_t, unsigned int,
+ enum ht_lookup_option);
+#define HT_HASHSTEP(r, c) ((r) * 67 + ((c) - 113));
+#define HT_HASHFINISH(r, len) ((r) + (len))
/* For all nodes in TABLE, make a callback. The callback takes
TABLE->PFILE, the node, and a PTR, and the callback sequence stops
diff --git a/libcpp/init.c b/libcpp/init.c
index d14da4d..65cca9b 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -429,18 +429,6 @@ static void sanity_checks (cpp_reader *pfile)
# define sanity_checks(PFILE)
#endif
-/* Add a dependency target. Can be called any number of times before
- cpp_read_main_file(). If no targets have been added before
- cpp_read_main_file(), then the default target is used. */
-void
-cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote)
-{
- if (!pfile->deps)
- pfile->deps = deps_init ();
-
- deps_add_target (pfile->deps, target, quote);
-}
-
/* This is called after options have been parsed, and partially
processed. */
void
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 9cd9be5..3608201 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -246,6 +246,10 @@ struct lexer_state
/* Nonzero when parsing arguments to a function-like macro. */
unsigned char parsing_args;
+ /* Nonzero if prevent_expansion is true only because output is
+ being discarded. */
+ unsigned char discarding_output;
+
/* Nonzero to skip evaluating part of an expression. */
unsigned int skip_eval;
};
diff --git a/libcpp/lex.c b/libcpp/lex.c
index a7d988b..37df6ef 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -470,22 +470,36 @@ static cpp_hashnode *
lex_identifier (cpp_reader *pfile, const uchar *base)
{
cpp_hashnode *result;
- const uchar *cur;
+ const uchar *cur, *limit;
+ unsigned int len;
+ unsigned int hash = HT_HASHSTEP (0, *base);
- do
+ cur = pfile->buffer->cur;
+ for (;;)
{
- cur = pfile->buffer->cur;
-
/* N.B. ISIDNUM does not include $. */
while (ISIDNUM (*cur))
- cur++;
+ {
+ hash = HT_HASHSTEP (hash, *cur);
+ cur++;
+ }
pfile->buffer->cur = cur;
+ if (!forms_identifier_p (pfile, false))
+ break;
+
+ limit = pfile->buffer->cur;
+ while (cur < limit)
+ {
+ hash = HT_HASHSTEP (hash, *cur);
+ cur++;
+ }
}
- while (forms_identifier_p (pfile, false));
+ len = cur - base;
+ hash = HT_HASHFINISH (hash, len);
result = (cpp_hashnode *)
- ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC);
+ ht_lookup_with_hash (pfile->hash_table, base, len, hash, HT_ALLOC);
/* Rarely, identifiers require diagnostics when lexed. */
if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC)
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 842c15c..cfc42b4 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -1142,12 +1142,18 @@ cpp_scan_nooutput (cpp_reader *pfile)
transparently continuing with the including file. */
pfile->buffer->return_at_eof = true;
+ pfile->state.discarding_output++;
+ pfile->state.prevent_expansion++;
+
if (CPP_OPTION (pfile, traditional))
while (_cpp_read_logical_line_trad (pfile))
;
else
while (cpp_get_token (pfile)->type != CPP_EOF)
;
+
+ pfile->state.discarding_output--;
+ pfile->state.prevent_expansion--;
}
/* Step back one (or more) tokens. Can only step mack more than 1 if
diff --git a/libcpp/makedepend.c b/libcpp/makedepend.c
new file mode 100644
index 0000000..df4a293
--- /dev/null
+++ b/libcpp/makedepend.c
@@ -0,0 +1,205 @@
+/* Dependency generator utility.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg, May 2004
+
+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 "line-map.h"
+#include "cpplib.h"
+#include "getopt.h"
+
+const char *progname;
+const char *vpath;
+
+static const char *output_file;
+static bool had_errors;
+
+/* Option lists, to give to cpplib before each input file. */
+struct cmd_line_macro
+{
+ struct cmd_line_macro *next;
+ bool is_undef;
+ const char *macro;
+};
+
+static struct cmd_line_macro *cmd_line_macros;
+static cpp_dir *cmd_line_searchpath;
+
+static void
+add_clm (const char *macro, bool is_undef)
+{
+ struct cmd_line_macro *clm = xmalloc (sizeof (struct cmd_line_macro));
+ clm->next = cmd_line_macros;
+ clm->is_undef = is_undef;
+ clm->macro = macro;
+ cmd_line_macros = clm;
+}
+
+static void
+add_dir (char *name, bool sysp)
+{
+ cpp_dir *dir = xmalloc (sizeof (cpp_dir));
+ dir->next = cmd_line_searchpath;
+ dir->name = name;
+ dir->sysp = sysp;
+ dir->construct = 0;
+ dir->user_supplied_p = 1;
+ cmd_line_searchpath = dir;
+}
+
+/* Command line processing. */
+
+static void ATTRIBUTE_NORETURN
+usage (int errcode)
+{
+ fprintf (stderr,
+"usage: %s [-vh] [-V vpath] [-Dname[=def]...] [-Uname] [-Idir...] [-o file] sources...\n",
+ progname);
+ exit (errcode);
+}
+
+static int
+parse_options (int argc, char **argv)
+{
+ static const struct option longopts[] = {
+ { "--help", no_argument, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+ for (;;)
+ switch (getopt_long (argc, argv, "hD:U:I:J:o:V:", longopts, 0))
+ {
+ case 'h': usage (0);
+ case 'D': add_clm (optarg, false); break;
+ case 'U': add_clm (optarg, true); break;
+ case 'I': add_dir (optarg, false); break;
+ case 'J': add_dir (optarg, true); break;
+ case 'o':
+ if (output_file)
+ {
+ fprintf (stderr, "%s: too many output files\n", progname);
+ usage (2);
+ }
+ output_file = optarg;
+ break;
+ case 'V':
+ if (vpath)
+ {
+ fprintf (stderr, "%s: too many vpaths\n", progname);
+ usage (2);
+ }
+ vpath = optarg;
+ break;
+ case '?':
+ usage (2); /* getopt has issued the error message. */
+
+ case -1: /* end of options */
+ if (optind == argc)
+ {
+ fprintf (stderr, "%s: no input files\n", progname);
+ usage (2);
+ }
+ return optind;
+
+ default:
+ abort ();
+ }
+}
+
+/* Set up cpplib from command line options. */
+static cpp_reader *
+reader_init (struct line_maps *line_table)
+{
+ cpp_reader *reader;
+ cpp_options *options;
+
+ linemap_init (line_table);
+ reader = cpp_create_reader (CLK_GNUC89, 0, line_table);
+
+ /* Ignore warnings and errors (we don't have access to system
+ headers). Request dependency output. */
+ options = cpp_get_options (reader);
+ options->inhibit_warnings = 1;
+ options->inhibit_errors = 1;
+ options->deps.style = DEPS_USER;
+
+ /* Further initialization. */
+ cpp_post_options (reader);
+ cpp_init_iconv (reader);
+ cpp_set_include_chains (reader, cmd_line_searchpath, cmd_line_searchpath,
+ false);
+ if (vpath)
+ {
+ struct deps *deps = cpp_get_deps (reader);
+ deps_add_vpath (deps, vpath);
+ }
+
+ return reader;
+}
+
+/* Process one input source file. */
+static void
+process_file (const char *file)
+{
+ struct line_maps line_table;
+ cpp_reader *reader = reader_init (&line_table);
+
+ if (!cpp_read_main_file (reader, file))
+ had_errors = true;
+ else
+ {
+ struct cmd_line_macro *clm;
+
+ cpp_init_builtins (reader, true);
+ for (clm = cmd_line_macros; clm; clm = clm->next)
+ (clm->is_undef ? cpp_undef : cpp_define) (reader, clm->macro);
+
+ cpp_scan_nooutput (reader);
+ if (cpp_finish (reader, stdout))
+ had_errors = true;
+ }
+ cpp_destroy (reader);
+ linemap_free (&line_table);
+}
+
+/* Master control. */
+
+int
+main(int argc, char **argv)
+{
+ int first_input, i;
+
+ progname = argv[0];
+ xmalloc_set_program_name (progname);
+
+ first_input = parse_options (argc, argv);
+ if (output_file)
+ if (!freopen (output_file, "w", stdout))
+ {
+ perror (output_file);
+ return 1;
+ }
+
+ for (i = first_input; i < argc; i++)
+ process_file (argv[i]);
+
+ return had_errors;
+}
diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c
index 23af9d8..5ab8813 100644
--- a/libcpp/mkdeps.c
+++ b/libcpp/mkdeps.c
@@ -35,6 +35,11 @@ struct deps
const char **depv;
unsigned int ndeps;
unsigned int deps_size;
+
+ const char **vpathv;
+ size_t *vpathlv;
+ unsigned int nvpaths;
+ unsigned int vpaths_size;
};
static const char *munge (const char *);
@@ -105,24 +110,48 @@ munge (const char *filename)
return buffer;
}
-/* Public routines. */
-
-struct deps *
-deps_init (void)
+/* If T begins with any of the partial pathnames listed in d->vpathv,
+ then advance T to point beyond that pathname. */
+static const char *
+apply_vpath (struct deps *d, const char *t)
{
- struct deps *d = xmalloc (sizeof (struct deps));
+ if (d->vpathv)
+ {
+ unsigned int i;
+ for (i = 0; i < d->nvpaths; i++)
+ {
+ if (!strncmp (d->vpathv[i], t, d->vpathlv[i]))
+ {
+ const char *p = t + d->vpathlv[i];
+ if (!IS_DIR_SEPARATOR (*p))
+ goto not_this_one;
+
+ /* Do not simplify $(vpath)/../whatever. ??? Might not
+ be necessary. */
+ if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
+ goto not_this_one;
+
+ /* found a match */
+ t = t + d->vpathlv[i] + 1;
+ break;
+ }
+ not_this_one:;
+ }
+ }
- /* Allocate space for the vectors only if we need it. */
+ /* Remove leading ./ in any case. */
+ while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
+ t += 2;
- d->targetv = 0;
- d->depv = 0;
+ return t;
+}
- d->ntargets = 0;
- d->targets_size = 0;
- d->ndeps = 0;
- d->deps_size = 0;
+/* Public routines. */
- return d;
+struct deps *
+deps_init (void)
+{
+ return xcalloc (sizeof (struct deps), 1);
}
void
@@ -144,6 +173,14 @@ deps_free (struct deps *d)
free (d->depv);
}
+ if (d->vpathv)
+ {
+ for (i = 0; i < d->nvpaths; i++)
+ free ((void *) d->vpathv[i]);
+ free (d->vpathv);
+ free (d->vpathlv);
+ }
+
free (d);
}
@@ -159,6 +196,7 @@ deps_add_target (struct deps *d, const char *t, int quote)
d->targets_size * sizeof (const char *));
}
+ t = apply_vpath (d, t);
if (quote)
t = munge (t); /* Also makes permanent copy. */
else
@@ -202,7 +240,7 @@ deps_add_default_target (struct deps *d, const char *tgt)
void
deps_add_dep (struct deps *d, const char *t)
{
- t = munge (t); /* Also makes permanent copy. */
+ t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */
if (d->ndeps == d->deps_size)
{
@@ -213,6 +251,36 @@ deps_add_dep (struct deps *d, const char *t)
}
void
+deps_add_vpath (struct deps *d, const char *vpath)
+{
+ const char *elem, *p;
+ char *copy;
+ size_t len;
+
+ for (elem = vpath; *elem; elem = p)
+ {
+ for (p = elem; *p && *p != ':'; p++);
+ len = p - elem;
+ copy = xmalloc (len + 1);
+ memcpy (copy, elem, len);
+ copy[len] = '\0';
+ if (*p == ':')
+ p++;
+
+ if (d->nvpaths == d->vpaths_size)
+ {
+ d->vpaths_size = d->vpaths_size * 2 + 8;
+ d->vpathv = xrealloc (d->vpathv,
+ d->vpaths_size * sizeof (const char *));
+ d->vpathlv = xrealloc (d->vpathlv, d->vpaths_size * sizeof (size_t));
+ }
+ d->vpathv[d->nvpaths] = copy;
+ d->vpathlv[d->nvpaths] = len;
+ d->nvpaths++;
+ }
+}
+
+void
deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
{
unsigned int size, i, column;
diff --git a/libcpp/symtab.c b/libcpp/symtab.c
index c80dfa2..9b2e0f1 100644
--- a/libcpp/symtab.c
+++ b/libcpp/symtab.c
@@ -41,13 +41,11 @@ calc_hash (const unsigned char *str, size_t len)
{
size_t n = len;
unsigned int r = 0;
-#define HASHSTEP(r, c) ((r) * 67 + ((c) - 113));
while (n--)
- r = HASHSTEP (r, *str++);
+ r = HT_HASHSTEP (r, *str++);
- return r + len;
-#undef HASHSTEP
+ return HT_HASHFINISH (r, len);
}
/* Initialize an identifier hashtable. */
@@ -96,7 +94,15 @@ hashnode
ht_lookup (hash_table *table, const unsigned char *str, size_t len,
enum ht_lookup_option insert)
{
- unsigned int hash = calc_hash (str, len);
+ return ht_lookup_with_hash (table, str, len, calc_hash (str, len),
+ insert);
+}
+
+hashnode
+ht_lookup_with_hash (hash_table *table, const unsigned char *str,
+ size_t len, unsigned int hash,
+ enum ht_lookup_option insert)
+{
unsigned int hash2;
unsigned int index;
size_t sizemask;