diff options
Diffstat (limited to 'contrib/gcclibs/libcpp')
-rw-r--r-- | contrib/gcclibs/libcpp/files.c | 77 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/internal.h | 4 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/lex.c | 30 |
3 files changed, 98 insertions, 13 deletions
diff --git a/contrib/gcclibs/libcpp/files.c b/contrib/gcclibs/libcpp/files.c index 8334218..3751184d 100644 --- a/contrib/gcclibs/libcpp/files.c +++ b/contrib/gcclibs/libcpp/files.c @@ -1,6 +1,7 @@ /* Part of CPP library. File handling. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Written by Per Bothner, 1994. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -26,6 +27,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "cpplib.h" #include "internal.h" #include "mkdeps.h" +#include "obstack.h" #include "hashtab.h" #include "md5.h" #include <dirent.h> @@ -322,6 +324,16 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (path) { + hashval_t hv = htab_hash_string (path); + char *copy; + void **pp; + + if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL) + { + file->err_no = ENOENT; + return false; + } + file->path = path; if (pch_open_file (pfile, file, invalid_pch)) return true; @@ -335,7 +347,16 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) return true; } + /* We copy the path name onto an obstack partly so that we don't + leak the memory, but mostly so that we don't fragment the + heap. */ + copy = obstack_copy0 (&pfile->nonexistent_file_ob, path, + strlen (path)); free (path); + pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash, + copy, hv, INSERT); + *pp = copy; + file->path = file->name; } else @@ -396,6 +417,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f struct file_hash_entry *entry, **hash_slot; _cpp_file *file; bool invalid_pch = false; + bool saw_bracket_include = false; + bool saw_quote_include = false; + struct cpp_dir *found_in_cache = NULL; /* Ensure we get no confusion between cached files and directories. */ if (start_dir == NULL) @@ -448,13 +472,19 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f /* 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) + if (file->dir == pfile->bracket_include) + saw_bracket_include = true; + else if (file->dir == pfile->quote_include) + saw_quote_include = true; + else continue; entry = search_cache (*hash_slot, file->dir); if (entry) - break; + { + found_in_cache = file->dir; + break; + } } if (entry) @@ -478,6 +508,29 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f entry->u.file = file; *hash_slot = entry; + /* If we passed the quote or bracket chain heads, cache them also. + This speeds up processing if there are lots of -I options. */ + if (saw_bracket_include + && pfile->bracket_include != start_dir + && found_in_cache != pfile->bracket_include) + { + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = pfile->bracket_include; + entry->u.file = file; + *hash_slot = entry; + } + if (saw_quote_include + && pfile->quote_include != start_dir + && found_in_cache != pfile->quote_include) + { + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = pfile->quote_include; + entry->u.file = file; + *hash_slot = entry; + } + return file; } @@ -997,6 +1050,14 @@ file_hash_eq (const void *p, const void *q) return strcmp (hname, fname) == 0; } +/* Compare entries in the nonexistent file hash table. These are just + strings. */ +static int +nonexistent_file_hash_eq (const void *p, const void *q) +{ + return strcmp (p, q) == 0; +} + /* Initialize everything in this source file. */ void _cpp_init_files (cpp_reader *pfile) @@ -1006,6 +1067,12 @@ _cpp_init_files (cpp_reader *pfile) pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, NULL, xcalloc, free); allocate_file_hash_entries (pfile); + pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string, + nonexistent_file_hash_eq, + NULL, xcalloc, free); + _obstack_begin (&pfile->nonexistent_file_ob, 0, 0, + (void *(*) (long)) xmalloc, + (void (*) (void *)) free); } /* Finalize everything in this source file. */ @@ -1014,6 +1081,8 @@ _cpp_cleanup_files (cpp_reader *pfile) { htab_delete (pfile->file_hash); htab_delete (pfile->dir_hash); + htab_delete (pfile->nonexistent_file_hash); + obstack_free (&pfile->nonexistent_file_ob, 0); } /* Enter a file name in the hash for the sake of cpp_included. */ diff --git a/contrib/gcclibs/libcpp/internal.h b/contrib/gcclibs/libcpp/internal.h index addff61..1661f7a 100644 --- a/contrib/gcclibs/libcpp/internal.h +++ b/contrib/gcclibs/libcpp/internal.h @@ -355,6 +355,10 @@ struct cpp_reader struct file_hash_entry *file_hash_entries; unsigned int file_hash_entries_allocated, file_hash_entries_used; + /* Negative path lookup hash table. */ + struct htab *nonexistent_file_hash; + struct obstack nonexistent_file_ob; + /* Nonzero means don't look for #include "foo" the source-file directory. */ bool quote_ignores_source_dir; diff --git a/contrib/gcclibs/libcpp/lex.c b/contrib/gcclibs/libcpp/lex.c index df09bd6..5d1a688 100644 --- a/contrib/gcclibs/libcpp/lex.c +++ b/contrib/gcclibs/libcpp/lex.c @@ -111,31 +111,39 @@ _cpp_clean_line (cpp_reader *pfile) if (!buffer->from_stage3) { + const uchar *pbackslash = NULL; + /* Short circuit for the common case of an un-escaped line with no trigraphs. The primary win here is by not writing any data back to memory until we have to. */ for (;;) { c = *++s; - if (c == '\n' || c == '\r') + if (__builtin_expect (c == '\n', false) + || __builtin_expect (c == '\r', false)) { d = (uchar *) s; - if (s == buffer->rlimit) + if (__builtin_expect (s == buffer->rlimit, false)) goto done; /* DOS line ending? */ - if (c == '\r' && s[1] == '\n') - s++; + if (__builtin_expect (c == '\r', false) + && s[1] == '\n') + { + s++; + if (s == buffer->rlimit) + goto done; + } - if (s == buffer->rlimit) + if (__builtin_expect (pbackslash == NULL, true)) goto done; - /* check for escaped newline */ + /* Check for escaped newline. */ p = d; - while (p != buffer->next_line && is_nvspace (p[-1])) + while (is_nvspace (p[-1])) p--; - if (p == buffer->next_line || p[-1] != '\\') + if (p - 1 != pbackslash) goto done; /* Have an escaped newline; process it and proceed to @@ -145,7 +153,11 @@ _cpp_clean_line (cpp_reader *pfile) buffer->next_line = p - 1; break; } - if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) + if (__builtin_expect (c == '\\', false)) + pbackslash = s; + else if (__builtin_expect (c == '?', false) + && __builtin_expect (s[1] == '?', false) + && _cpp_trigraph_map[s[2]]) { /* Have a trigraph. We may or may not have to convert it. Add a line note regardless, for -Wtrigraphs. */ |