/* Try each path in the include chain. */
for (; !fake ;)
{
+ if (file->dir == pfile->quote_include
+ || file->dir == pfile->bracket_include)
+ {
+ entry = search_cache (*hash_slot, file->dir);
+ if (entry)
+ {
+ /* Found the same file again. Record it as reachable
+ from this position, too. */
+ free ((char *) file->name);
+ free (file);
+ file = entry->u.file;
+ goto found;
+ }
+ }
+
if (find_file_in_dir (pfile, file, &invalid_pch))
break;
}
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)
- {
- /* Cache for START_DIR too, sharing the _cpp_file structure. */
- free ((char *) file->name);
- free (file);
- file = entry->u.file;
- }
- else
+ /* This is a new file; put it in the list. */
+ file->next_file = pfile->all_files;
+ 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)
{
- /* This is a new file; put it in the list. */
- file->next_file = pfile->all_files;
- pfile->all_files = file;
+ 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;
}
+ found:
/* Store this new result in the hash table. */
entry = new_file_hash_entry (pfile);
entry->next = *hash_slot;
/* Handle PCH files immediately; don't stack them. */
if (file->pch)
{
- pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname);
+ pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path);
close (file->fd);
file->fd = -1;
return false;
static struct file_hash_entry *
search_cache (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;
- return head;
+ /* 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;
+ return 0;
}
/* Allocate a new _cpp_file structure. */
cpp_dir *dir;
hash_slot = (struct file_hash_entry **)
- htab_find_slot_with_hash (pfile->file_hash, dir_name,
+ htab_find_slot_with_hash (pfile->dir_hash, dir_name,
htab_hash_string (dir_name),
INSERT);
{
pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
NULL, xcalloc, free);
+ pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
+ NULL, xcalloc, free);
allocate_file_hash_entries (pfile);
}
_cpp_cleanup_files (cpp_reader *pfile)
{
htab_delete (pfile->file_hash);
+ htab_delete (pfile->dir_hash);
}
/* Enter a file name in the hash for the sake of cpp_included. */