diff options
author | Zack Weinberg <zack@gcc.gnu.org> | 2004-06-05 20:58:06 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2004-06-05 20:58:06 +0000 |
commit | c6e8380069ff630939beec0b5872a37f5b710189 (patch) | |
tree | f9776b653c83d7c1faa17b330fe162333d109cc2 /libcpp | |
parent | dbeff3e56d566719bb3f0c1ba29362d61fe3ff85 (diff) | |
download | gcc-c6e8380069ff630939beec0b5872a37f5b710189.zip gcc-c6e8380069ff630939beec0b5872a37f5b710189.tar.gz gcc-c6e8380069ff630939beec0b5872a37f5b710189.tar.bz2 |
Makefile.am: Add makedepend.
libcpp:
* 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.
gcc:
* Makefile.in (MKDEPS_H): New shorthand.
(c-opts.o): Update dependencies.
* c-opts.c: Include mkdeps.h.
(handle_deferred_opts): Use cpp_get_deps and deps_add_target,
not cpp_add_dependency_target.
From-SVN: r82654
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 31 | ||||
-rw-r--r-- | libcpp/Makefile.am | 3 | ||||
-rw-r--r-- | libcpp/Makefile.in | 60 | ||||
-rw-r--r-- | libcpp/aclocal.m4 | 4 | ||||
-rw-r--r-- | libcpp/charset.c | 2 | ||||
-rw-r--r-- | libcpp/directives.c | 43 | ||||
-rw-r--r-- | libcpp/files.c | 79 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 13 | ||||
-rw-r--r-- | libcpp/include/mkdeps.h | 7 | ||||
-rw-r--r-- | libcpp/include/symtab.h | 5 | ||||
-rw-r--r-- | libcpp/init.c | 12 | ||||
-rw-r--r-- | libcpp/internal.h | 4 | ||||
-rw-r--r-- | libcpp/lex.c | 28 | ||||
-rw-r--r-- | libcpp/macro.c | 6 | ||||
-rw-r--r-- | libcpp/makedepend.c | 205 | ||||
-rw-r--r-- | libcpp/mkdeps.c | 96 | ||||
-rw-r--r-- | libcpp/symtab.c | 16 |
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; |