This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

branch: Sync CPP with trunk.


This is the last time I intend to sync.  The trunk has survived OK for
a couple of weeks without complaints, and the file handling work fixed
a fair few issues, so this brings them both in line again.

I've bootstrapped and made check, and built glibc successfully with this.
A Glibc make check failed in the math subdirectory, but I don't think
that's related.  I'll commit this in about 8 hours; I'm going to bed now.

Neil.

	* cppfiles.c: Update comments.
	(struct include_file): Remove "defined" memeber.
	(find_or_create_entry): Make a copy of the file name, and
	simplify it.
	(open_file): Update to ensure we use the simplified filename.
	(stack_include_file): Don't set search_from.
	(cpp_included): Don't simplify the path name here.
	(find_include_file): New prototype.  Call search_from to
	get the start of the "" include chain.  Don't simplify the
	filenames here.
	(_cpp_execute_include): New prototype.  Move diagnostics to
	do_include_common.  Update.
	(_cpp_pop_file_buffer): Don't set defined.
	(search_from): New prototype.  Use the preprocessor's cwd
	for files included from the command line.
	(read_name_map): Don't simplify the pathname here.

	(stack_include_file): Only increase the include
	count if we actually process the file properly, as opposed
	to treating it as length zero.  Only call read_include_file
	if not DO_NOT_REREAD.  Handle the -H include file output
	here.
	(read_include_file): Remove now redundant DO_NOT_REREAD check.
	(cpp_included, find_include_file): Simplify pathnames after
	remapping them.  If remapping, don't use the remapped file
	name's buffer as our scratch buffer.
	(cpp_pop_file_buffer): Replace the multiple include macro
	only if it isn't yet set.
	(read_name_map): Simplify remapped names when reading in.
	(remap_filename): Move code to code path that uses it.
	(_cpp_simplify_pathname): Return the input pointer.

	(NO_INCLUDE_PATH): New macro.
	(find_include_file): Decide here which part of the include
	chain to start the search.  Complain about an empty include
	chain in all cases apart from an abolsute file name.
	(_cpp_execute_include): Don't choose the search chain here.
	Don't call handle_missing_include in the case of an empty
	include chain.
	(_cpp_compare_file_date): Don't choose the search chain here.

	(destroy_include_file_node): Rename destroy_node.
	(find_or_create_entry): New function.
	(open_file, _cpp_fake_include): Use it.
	(handle_missing_header): New function, broken out of
	_cpp_execute include.  Don't segfault if there is no
	system or quoted path.
	(_cpp_execute_include): Use handle_missing_header.

	(INCLUDE_LEN_FUDGE, ENOMEM): Delete.
	(cpp_included, find_include_file): Update.
	(search_from): Use lbasename.
	(_cpp_execute_include): Don't make a null-terminated
	copy of the filename.  Don't use CPP_PREV_BUFFER.  Don't call
	strlen or strcpy; we already know the length.
	(_cpp_compare_file_date): Similarly.

	* cpphash.h: Update comments.
	(enum include_type): New.
	(struct buffer): Delete search from.  New search_cached.
	(_cpp_execute_include): Update prototype.
	(struct cpp_reader): Delete done_initialising.
	(_cpp_simplify_pathname): Update prototype.
	(struct cpp_buffer): Delete actual_dir.  New members
	search_from and dir.
	(struct cpp_reader): Remove actual_dirs.

	(struct include_file): Update.
	(stack_include_file): Use search_from.
	(cpp_included, find_include_file): Update.
	(cpp_execute_include): Update.  ptr->name may not be
	null terminated.  Use the new search_from member variable
	of cpp_buffer.
	(_cpp_compare_file_date): Similarly.
	(search_from): New function, similiar to actual_directory.
	(actual_directory): Delete.
	(remap_filename): Update.  loc->name may not be null terminated.
	(struct file_name_list): Rename search_path.  Update.

	* cppinit.c (do_includes): Use _cpp_execute_include.
	(cpp_start_read): Don't set done_initialising.
	(struct cpp_pending): Update for renamed objects.
	(append_include_chain, remove_dup_dir, remove_dup_dirs,
	merge_include_chains, cpp_destroy, cpp_start_read): Similarly.

	* cpplib.c (do_include_common): New function.
	(do_include, do_include_next, do_import): Use it.
	(do_include_next): Move the in-main-file diagnostic
	here from _cpp_execute_include.  Behave like #include if
	we're in the main file.
	(_cpp_compare_file_date): Make else unconditional.
	(CPP_PREV_BUFFER): Delete.
	(glue_header_name): Null-terminate.
	(do_line): Don't leak memory.

	* cpplex.c (parse_string): Guarantee null-termination.
	(_cpp_equiv_toklists): Remove.

	* cpplib.h (BT_WEAK): Delete.
	(struct cpp_options): Update.

	* cppmain.c (cb_ident): Strings are now null-terminated.

	* mkdeps.c (deps_add_default_target): Use lbasename.

Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.101.4.4
diff -u -p -r1.101.4.4 cppfiles.c
--- cppfiles.c	2001/03/16 05:16:27	1.101.4.4
+++ cppfiles.c	2001/03/26 22:14:22
@@ -43,10 +43,6 @@ Foundation, 59 Temple Place - Suite 330,
 # define O_BINARY 0
 #endif
 
-#ifndef INCLUDE_LEN_FUDGE
-# define INCLUDE_LEN_FUDGE 0
-#endif
-
 /* If errno is inspected immediately after a system call fails, it will be
    nonzero, and no error number will ever be zero.  */
 #ifndef ENOENT
@@ -55,9 +51,6 @@ Foundation, 59 Temple Place - Suite 330,
 #ifndef ENOTDIR
 # define ENOTDIR 0
 #endif
-#ifndef ENOMEM
-# define ENOMEM 0
-#endif
 
 /* Suppress warning about function macros used w/o arguments in traditional
    C.  It is unlikely that glibc's strcmp macro helps this file at all.  */
@@ -68,7 +61,7 @@ struct include_file
 {
   const char *name;		/* actual path name of file */
   const cpp_hashnode *cmacro;	/* macro, if any, preventing reinclusion.  */
-  const struct file_name_list *foundhere;
+  const struct search_path *foundhere;
 				/* location in search path where file was
 				   found, for #include_next and sysp.  */
   const unsigned char *buffer;	/* pointer to cached file contents */
@@ -77,54 +70,50 @@ struct include_file
   unsigned short include_count;	/* number of times file has been read */
   unsigned short refcnt;	/* number of stacked buffers using this file */
   unsigned char mapped;		/* file buffer is mmapped */
-  unsigned char defined;	/* cmacro prevents inclusion in this state */
 };
 
 /* The cmacro works like this: If it's NULL, the file is to be
    included again.  If it's NEVER_REREAD, the file is never to be
    included again.  Otherwise it is a macro hashnode, and the file is
-   to be included again if the macro is defined or not as specified by
-   DEFINED.  */
+   to be included again if the macro is defined.  */
 #define NEVER_REREAD ((const cpp_hashnode *)-1)
 #define DO_NOT_REREAD(inc) \
 ((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
-		   || ((inc)->cmacro->type == NT_MACRO) == (inc)->defined))
+		   || (inc)->cmacro->type == NT_MACRO))
+#define NO_INCLUDE_PATH ((struct include_file *) -1)
 
 static struct file_name_map *read_name_map
 				PARAMS ((cpp_reader *, const char *));
 static char *read_filename_string PARAMS ((int, FILE *));
 static char *remap_filename 	PARAMS ((cpp_reader *, char *,
-					 struct file_name_list *));
-static struct file_name_list *actual_directory
-				PARAMS ((cpp_reader *, const char *));
-static struct include_file *find_include_file
-				PARAMS ((cpp_reader *, const char *,
-					 struct file_name_list *));
+					 struct search_path *));
+static struct search_path *search_from PARAMS ((cpp_reader *,
+						enum include_type));
+static struct include_file *
+	find_include_file PARAMS ((cpp_reader *, const cpp_token *,
+				   enum include_type));
 static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
 static void read_include_file	PARAMS ((cpp_reader *, struct include_file *));
 static void stack_include_file	PARAMS ((cpp_reader *, struct include_file *));
 static void purge_cache 	PARAMS ((struct include_file *));
-static void destroy_include_file_node	PARAMS ((splay_tree_value));
+static void destroy_node	PARAMS ((splay_tree_value));
 static int report_missing_guard		PARAMS ((splay_tree_node, void *));
-
-/* We use a splay tree to store information about all the include
-   files seen in this compilation.  The key of each tree node is the
-   physical path to the file.  The value is 0 if the file does not
-   exist, or a struct include_file pointer.  */
-
-static void
-destroy_include_file_node (v)
-     splay_tree_value v;
-{
-  struct include_file *f = (struct include_file *)v;
-
-  if (f)
-    {
-      purge_cache (f);
-      free (f);  /* The tree is registered with free to free f->name.  */
-    }
-}
+static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
+						     const char *));
+static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
+
+/* Set up the splay tree we use to store information about all the
+   file names seen in this compilation.  We also have entries for each
+   file we tried to open but failed; this saves system calls since we
+   don't try to open it again in future.
+
+   The key of each node is the file name, after processing by
+   _cpp_simplify_pathname.  The path name may or may not be absolute.
+   The path string has been malloced, as is automatically freed by
+   registering free () as the splay tree key deletion function.
 
+   A node's value is a pointer to a struct include_file, and is never
+   NULL.  */
 void
 _cpp_init_includes (pfile)
      cpp_reader *pfile;
@@ -132,9 +121,10 @@ _cpp_init_includes (pfile)
   pfile->all_include_files
     = splay_tree_new ((splay_tree_compare_fn) strcmp,
 		      (splay_tree_delete_key_fn) free,
-		      destroy_include_file_node);
+		      destroy_node);
 }
 
+/* Tear down the splay tree.  */
 void
 _cpp_cleanup_includes (pfile)
      cpp_reader *pfile;
@@ -142,6 +132,20 @@ _cpp_cleanup_includes (pfile)
   splay_tree_delete (pfile->all_include_files);
 }
 
+/* Free a node.  The path string is automatically freed.  */
+static void
+destroy_node (v)
+     splay_tree_value v;
+{
+  struct include_file *f = (struct include_file *)v;
+
+  if (f)
+    {
+      purge_cache (f);
+      free (f);
+    }
+}
+
 /* Mark a file to not be reread (e.g. #import, read failure).  */
 void
 _cpp_never_reread (file)
@@ -150,24 +154,40 @@ _cpp_never_reread (file)
   file->cmacro = NEVER_REREAD;
 }
 
-/* Put a file name in the splay tree, for the sake of cpp_included ().
-   Assume that FNAME has already had its path simplified.  */
-void
-_cpp_fake_include (pfile, fname)
+/* Lookup a filename, which is simplified after making a copy, and
+   create an entry if none exists.  */
+static splay_tree_node
+find_or_create_entry (pfile, fname)
      cpp_reader *pfile;
      const char *fname;
 {
-  splay_tree_node nd;
+  splay_tree_node node;
+  struct include_file *file;
+  char *name = xstrdup (fname);
 
-  nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
-  if (! nd)
+  _cpp_simplify_pathname (name);
+  node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
+  if (node)
+    free (name);
+  else
     {
-      struct include_file *file = xcnew (struct include_file);
-      file->name = xstrdup (fname);
-      splay_tree_insert (pfile->all_include_files,
-			 (splay_tree_key) file->name,
-			 (splay_tree_value) file);
+      file = xcnew (struct include_file);
+      file->name = name;
+      node = splay_tree_insert (pfile->all_include_files,
+				(splay_tree_key) file->name,
+				(splay_tree_value) file);
     }
+
+  return node;
+}
+
+/* Enter a file name in the splay tree, for the sake of cpp_included.  */
+void
+_cpp_fake_include (pfile, fname)
+     cpp_reader *pfile;
+     const char *fname;
+{
+  find_or_create_entry (pfile, fname);
 }
 
 /* Given a file name, look it up in the cache; if there is no entry,
@@ -185,36 +205,20 @@ open_file (pfile, filename)
      cpp_reader *pfile;
      const char *filename;
 {
-  splay_tree_node nd;
-  struct include_file *file;
-
-  nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) filename);
-
-  if (nd)
-    {
-      file = (struct include_file *) nd->value;
-
-      /* Don't retry opening if we failed previously.  */
-      if (file->fd == -2)
-	return 0;
+  splay_tree_node nd = find_or_create_entry (pfile, filename);
+  struct include_file *file = (struct include_file *) nd->value;
 
-      /* Don't reopen an idempotent file. */
-      if (DO_NOT_REREAD (file))
-        return file;
+  /* Don't retry opening if we failed previously.  */
+  if (file->fd == -2)
+    return 0;
+
+  /* Don't reopen an idempotent file. */
+  if (DO_NOT_REREAD (file))
+    return file;
       
-      /* Don't reopen one which is already loaded. */
-      if (file->buffer != NULL)
-        return file;
-    }
-  else
-    {
-      /* In particular, this clears foundhere.  */
-      file = xcnew (struct include_file);
-      file->name = xstrdup (filename);
-      splay_tree_insert (pfile->all_include_files,
-			 (splay_tree_key) file->name,
-			 (splay_tree_value) file);
-    }
+  /* Don't reopen one which is already loaded. */
+  if (file->buffer != NULL)
+    return file;
 
   /* We used to open files in nonblocking mode, but that caused more
      problems than it solved.  Do take care not to acquire a
@@ -233,7 +237,7 @@ open_file (pfile, filename)
   if (filename[0] == '\0')
     file->fd = 0;
   else
-    file->fd = open (filename, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
+    file->fd = open (file->name, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
 
   if (file->fd != -1 && fstat (file->fd, &file->st) == 0)
     {
@@ -250,7 +254,7 @@ open_file (pfile, filename)
 
   /* Don't issue an error message if the file doesn't exist.  */
   if (errno != ENOENT && errno != ENOTDIR)
-    cpp_error_from_errno (pfile, filename);
+    cpp_error_from_errno (pfile, file->name);
 
   /* Create a negative node for this path, and return null.  */
   file->fd = -2;
@@ -260,7 +264,7 @@ open_file (pfile, filename)
 
 /* Place the file referenced by INC into a new buffer on PFILE's
    stack.  If there are errors, or the file should not be re-included,
-   a null buffer is pushed.  */
+   a null (zero-length) buffer is pushed.  */
 
 static void
 stack_include_file (pfile, inc)
@@ -280,16 +284,27 @@ stack_include_file (pfile, inc)
   if (CPP_OPTION (pfile, print_deps) > deps_sysp && !inc->include_count)
     deps_add_dep (pfile->deps, inc->name);
 
-  /* We don't want multiple include guard advice for the main file.  */
-  if (pfile->buffer)
-    inc->include_count++;
-
-  /* Not in cache?  */
-  if (! inc->buffer)
-    read_include_file (pfile, inc);
-
   if (! DO_NOT_REREAD (inc))
-    len = inc->st.st_size;
+    {
+      /* Not in cache?  */
+      if (! inc->buffer)
+	read_include_file (pfile, inc);
+      len = inc->st.st_size;
+
+      if (pfile->buffer)
+	{
+	  /* We don't want MI guard advice for the main file.  */
+	  inc->include_count++;
+
+	  /* Handle -H option.  */
+	  if (CPP_OPTION (pfile, print_include_names))
+	    {
+	      for (fp = pfile->buffer; fp; fp = fp->prev)
+		putc ('.', stderr);
+	      fprintf (stderr, " %s\n", inc->name);
+	    }
+	}
+    }
 
   /* Push a buffer.  */
   fp = cpp_push_buffer (pfile, inc->buffer, len, BUF_FILE, inc->name);
@@ -297,11 +312,6 @@ stack_include_file (pfile, inc)
   fp->inc->refcnt++;
   fp->sysp = sysp;
 
-  /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
-     see do_include */
-  if (!CPP_OPTION (pfile, ignore_srcdir))
-    fp->actual_dir = actual_directory (pfile, inc->name);
-
   /* Initialise controlling macro state.  */
   pfile->mi_state = MI_OUTSIDE;
   pfile->mi_cmacro = 0;
@@ -339,9 +349,6 @@ read_include_file (pfile, inc)
   static int pagesize = -1;
 #endif
 
-  if (DO_NOT_REREAD (inc))
-    return;
-
   if (S_ISREG (inc->st.st_mode))
     {
       /* off_t might have a wider range than ssize_t - in other words,
@@ -461,8 +468,8 @@ cpp_included (pfile, fname)
      cpp_reader *pfile;
      const char *fname;
 {
-  struct file_name_list *path;
-  char *name;
+  struct search_path *path;
+  char *name, *n;
   splay_tree_node nd;
 
   if (IS_ABSOLUTE_PATHNAME (fname))
@@ -473,60 +480,80 @@ cpp_included (pfile, fname)
     }
       
   /* Search directory path for the file.  */
-  name = (char *) alloca (strlen (fname) + pfile->max_include_len
-			  + 2 + INCLUDE_LEN_FUDGE);
+  name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
   for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
     {
-      memcpy (name, path->name, path->nlen);
-      name[path->nlen] = '/';
-      strcpy (&name[path->nlen+1], fname);
-      _cpp_simplify_pathname (name);
+      memcpy (name, path->name, path->len);
+      name[path->len] = '/';
+      strcpy (&name[path->len + 1], fname);
       if (CPP_OPTION (pfile, remap))
-	name = remap_filename (pfile, name, path);
+	n = remap_filename (pfile, name, path);
+      else
+	n = name;
 
-      nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
+      nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) n);
       if (nd && nd->value)
 	return 1;
     }
   return 0;
 }
 
-/* Search for include file FNAME in the include chain starting at
-   SEARCH_START.  Return 0 if there is no such file (or it's un-openable),
-   otherwise an include_file structure.  */
+/* Search for HEADER.  Return 0 if there is no such file (or it's
+   un-openable), in which case an error code will be in errno.  If
+   there is no include path to use it returns NO_INCLUDE_PATH,
+   otherwise an include_file structure.  If this request originates
+   from a #include_next directive, set INCLUDE_NEXT to true.  */
 
 static struct include_file *
-find_include_file (pfile, fname, search_start)
+find_include_file (pfile, header, type)
      cpp_reader *pfile;
-     const char *fname;
-     struct file_name_list *search_start;
+     const cpp_token *header;
+     enum include_type type;
 {
-  struct file_name_list *path;
-  char *name;
+  const char *fname = (const char *) header->val.str.text;
+  struct search_path *path;
   struct include_file *file;
+  char *name, *n;
 
   if (IS_ABSOLUTE_PATHNAME (fname))
     return open_file (pfile, fname);
-      
+
+  /* For #include_next, skip in the search path past the dir in which
+     the current file was found, but if it was found via an absolute
+     path use the normal search logic.  */
+  if (type == IT_INCLUDE_NEXT && pfile->buffer->inc->foundhere)
+    path = pfile->buffer->inc->foundhere->next;
+  else if (header->type == CPP_HEADER_NAME)
+    path = CPP_OPTION (pfile, bracket_include);
+  else
+    path = search_from (pfile, type);
+
+  if (path == NULL)
+    {
+      cpp_error (pfile, "No include path in which to find %s", fname);
+      return NO_INCLUDE_PATH;
+    }
+
   /* Search directory path for the file.  */
-  name = (char *) alloca (strlen (fname) + pfile->max_include_len
-			  + 2 + INCLUDE_LEN_FUDGE);
-  for (path = search_start; path; path = path->next)
-    {
-      memcpy (name, path->name, path->nlen);
-      name[path->nlen] = '/';
-      strcpy (&name[path->nlen+1], fname);
-      _cpp_simplify_pathname (name);
+  name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
+  for (; path; path = path->next)
+    {
+      memcpy (name, path->name, path->len);
+      name[path->len] = '/';
+      strcpy (&name[path->len + 1], fname);
       if (CPP_OPTION (pfile, remap))
-	name = remap_filename (pfile, name, path);
+	n = remap_filename (pfile, name, path);
+      else
+	n = name;
 
-      file = open_file (pfile, name);
+      file = open_file (pfile, n);
       if (file)
 	{
 	  file->foundhere = path;
 	  return file;
 	}
     }
+
   return 0;
 }
 
@@ -580,178 +607,102 @@ report_missing_guard (n, b)
   return 0;
 }
 
-void
-_cpp_execute_include (pfile, header, no_reinclude, include_next)
+/* Create a dependency, or issue an error message as appropriate.   */
+static void
+handle_missing_header (pfile, fname, angle_brackets)
      cpp_reader *pfile;
-     const cpp_token *header;
-     int no_reinclude;
-     int include_next;
+     const char *fname;
+     int angle_brackets;
 {
-  struct file_name_list *search_start = 0;
-  unsigned int len = header->val.str.len;
-  unsigned int angle_brackets = header->type == CPP_HEADER_NAME;
-  struct include_file *inc;
-  char *fname;
-  int print_dep;
-
-  /* Help protect #include or similar from recursion.  */
-  if (pfile->buffer_stack_depth >= CPP_STACK_MAX)
-    {
-      cpp_fatal (pfile, "#include nested too deeply");
-      return;
-    }
-
-  /* Check we've tidied up #include before entering the buffer.  */
-  if (pfile->context->prev)
-    {
-      cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
-      return;
-    }
-
-  /* For #include_next, skip in the search path past the dir in which
-     the current file was found.  If this is the last directory in the
-     search path, don't include anything.  If the current file was
-     specified with an absolute path, use the normal search logic.  If
-     this is the primary source file, use the normal search logic and
-     generate a warning.  */
-  if (include_next)
-    {
-      if (! pfile->buffer->prev)
-	cpp_warning (pfile, "#include_next in primary source file");
-      else
-	{
-	  if (pfile->buffer->inc->foundhere)
-	    {
-	      search_start = pfile->buffer->inc->foundhere->next;
-	      if (! search_start)
-		return;
-	    }
-	}
-    }
-
-  fname = alloca (len + 1);
-  memcpy (fname, header->val.str.text, len);
-  fname[len] = '\0';
-
-  if (!search_start)
-    {
-      if (angle_brackets)
-	search_start = CPP_OPTION (pfile, bracket_include);
-      else if (CPP_OPTION (pfile, ignore_srcdir))
-	search_start = CPP_OPTION (pfile, quote_include);
-      else
-	search_start = CPP_BUFFER (pfile)->actual_dir;
-
-      if (!search_start)
-	{
-	  cpp_error (pfile, "No include path in which to find %s", fname);
-	  return;
-	}
-    }
-
-  inc = find_include_file (pfile, fname, search_start);
-  if (inc)
-    {
-      if (angle_brackets)
-	pfile->system_include_depth++;
-
-      stack_include_file (pfile, inc);
-
-      if (! DO_NOT_REREAD (inc))
-	{
-	  if (no_reinclude)
-	    _cpp_never_reread (inc);
-
-	  /* Handle -H option.  */
-	  if (CPP_OPTION (pfile, print_include_names))
-	    {
-	      cpp_buffer *fp = CPP_BUFFER (pfile);
-	      while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
-		putc ('.', stderr);
-	      fprintf (stderr, " %s\n", inc->name);
-	    }
-	}
-
-      return;
-    }
-      
   /* We will try making the RHS pfile->buffer->sysp after 3.0.  */
-  print_dep = CPP_PRINT_DEPS(pfile) > (angle_brackets
-				       || pfile->system_include_depth);
+  int print_dep = CPP_PRINT_DEPS(pfile) > (angle_brackets
+					   || pfile->system_include_depth);
   if (CPP_OPTION (pfile, print_deps_missing_files) && print_dep)
     {
       if (!angle_brackets || IS_ABSOLUTE_PATHNAME (fname))
 	deps_add_dep (pfile->deps, fname);
       else
 	{
+	  /* If requested as a system header, assume it belongs in
+	     the first system header directory.  */
+	  struct search_path *ptr = CPP_OPTION (pfile, bracket_include);
 	  char *p;
-	  struct file_name_list *ptr;
-	  int len;
+	  int len = 0, fname_len = strlen (fname);
 
-	  /* If requested as a system header, assume it belongs in
-	     the first system header directory. */
-	  if (CPP_OPTION (pfile, bracket_include))
-	    ptr = CPP_OPTION (pfile, bracket_include);
-	  else
-	    ptr = CPP_OPTION (pfile, quote_include);
+	  if (ptr)
+	    len = ptr->len;
 
-	  len = strlen (ptr->name);
-	  p = (char *) alloca (len + strlen (fname) + 2);
+	  p = (char *) alloca (len + fname_len + 2);
 	  if (len)
 	    {
 	      memcpy (p, ptr->name, len);
 	      p[len++] = '/';
 	    }
-	  strcpy (p + len, fname);
+	  memcpy (p + len, fname, fname_len + 1);
 	  _cpp_simplify_pathname (p);
 	  deps_add_dep (pfile->deps, p);
 	}
     }
-  /* If -M was specified, and this header file won't be added to
-     the dependency list, then don't count this as an error,
-     because we can still produce correct output.  Otherwise, we
-     can't produce correct output, because there may be
-     dependencies we need inside the missing file, and we don't
-     know what directory this missing file exists in. */
+  /* If -M was specified, then don't count this as an error, because
+     we can still produce correct output.  Otherwise, we can't produce
+     correct output, because there may be dependencies we need inside
+     the missing file, and we don't know what directory this missing
+     file exists in.  FIXME: Use a future cpp_diagnotic_with_errno ()
+     for both of these cases.  */
   else if (CPP_PRINT_DEPS (pfile) && ! print_dep)
-    cpp_warning (pfile, "No include path in which to find %s", fname);
+    cpp_warning (pfile, "%s: %s", fname, xstrerror (errno));
   else
     cpp_error_from_errno (pfile, fname);
 }
 
-/* Locate file F, and determine whether it is newer than PFILE. Return -1,
-   if F cannot be located or dated, 1, if it is newer and 0 if older.  */
+/* Returns non-zero if a buffer was stacked.  */
 int
-_cpp_compare_file_date (pfile, f)
+_cpp_execute_include (pfile, header, type)
      cpp_reader *pfile;
-     const cpp_token *f;
+     const cpp_token *header;
+     enum include_type type;
 {
-  unsigned int len = f->val.str.len;
-  char *fname;
-  struct file_name_list *search_start;
-  struct include_file *inc;
-
-  if (f->type == CPP_HEADER_NAME)
-    search_start = CPP_OPTION (pfile, bracket_include);
-  else if (CPP_OPTION (pfile, ignore_srcdir))
-    search_start = CPP_OPTION (pfile, quote_include);
-  else
-    search_start = CPP_BUFFER (pfile)->actual_dir;
+  struct include_file *inc = find_include_file (pfile, header, type);
 
-  fname = alloca (len + 1);
-  memcpy (fname, f->val.str.text, len);
-  fname[len] = '\0';
-  inc = find_include_file (pfile, fname, search_start);
+  if (inc == 0)
+    handle_missing_header (pfile, (const char *) header->val.str.text,
+			   header->type == CPP_HEADER_NAME);
+  else if (inc != NO_INCLUDE_PATH)
+    {
+      if (header->type == CPP_HEADER_NAME)
+	pfile->system_include_depth++;
+
+      stack_include_file (pfile, inc);
+
+      if (type == IT_IMPORT)
+	_cpp_never_reread (inc);
+
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Locate HEADER, and determine whether it is newer than the current
+   file.  If it cannot be located or dated, return -1, if it is newer
+   newer, return 1, otherwise 0.  */
+int
+_cpp_compare_file_date (pfile, header)
+     cpp_reader *pfile;
+     const cpp_token *header;
+{
+  struct include_file *inc = find_include_file (pfile, header, 0);
   
-  if (!inc)
+  if (inc == NULL || inc == NO_INCLUDE_PATH)
     return -1;
+
   if (inc->fd > 0)
     {
       close (inc->fd);
       inc->fd = -1;
     }
     
-  return inc->st.st_mtime > CPP_BUFFER (pfile)->inc->st.st_mtime;
+  return inc->st.st_mtime > pfile->buffer->inc->st.st_mtime;
 }
 
 
@@ -788,13 +739,10 @@ _cpp_pop_file_buffer (pfile, buf)
   if (pfile->include_depth)
     pfile->include_depth--;
 
-  /* Record the inclusion-preventing macro and its definedness.  */
-  if (pfile->mi_state == MI_OUTSIDE && inc->cmacro != NEVER_REREAD)
-    {
-      /* This could be NULL meaning no controlling macro.  */
-      inc->cmacro = pfile->mi_cmacro;
-      inc->defined = 1;
-    }
+  /* Record the inclusion-preventing macro, which could be NULL
+     meaning no controlling macro, if we haven't got it already.  */
+  if (pfile->mi_state == MI_OUTSIDE && inc->cmacro == NULL)
+    inc->cmacro = pfile->mi_cmacro;
 
   /* Invalidate control macros in the #including file.  */
   pfile->mi_state = MI_FAILED;
@@ -804,6 +752,61 @@ _cpp_pop_file_buffer (pfile, buf)
     purge_cache (inc);
 }
 
+/* Returns the first place in the include chain to start searching for
+   "" includes.  This involves stripping away the basename of the
+   current file, unless -I- was specified.
+
+   If we're handling -include or -imacros, use the "" chain, but with
+   the preprocessor's cwd prepended.  */
+static struct search_path *
+search_from (pfile, type)
+     cpp_reader *pfile;
+     enum include_type type;
+{
+  cpp_buffer *buffer = pfile->buffer;
+  unsigned int dlen;
+
+  /* Command line uses the cwd, and does not cache the result.  */
+  if (type == IT_CMDLINE)
+    goto use_cwd;
+
+  /* Ignore the current file's directory if -I- was given.  */
+  if (CPP_OPTION (pfile, ignore_srcdir))
+    return CPP_OPTION (pfile, quote_include);
+
+  if (! buffer->search_cached)
+    {
+      buffer->search_cached = 1;
+
+      dlen = lbasename (buffer->inc->name) - buffer->inc->name;
+
+      if (dlen)
+	{
+	  /* We don't guarantee NAME is null-terminated.  This saves
+	     allocating and freeing memory, and duplicating it when faking
+	     buffers in cpp_push_buffer.  Drop a trailing '/'.  */
+	  buffer->dir.name = buffer->inc->name;
+	  if (dlen > 1)
+	    dlen--;
+	}
+      else
+	{
+	use_cwd:
+	  buffer->dir.name = ".";
+	  dlen = 1;
+	}
+
+      if (dlen > pfile->max_include_len)
+	pfile->max_include_len = dlen;
+
+      buffer->dir.len = dlen;
+      buffer->dir.next = CPP_OPTION (pfile, quote_include);
+      buffer->dir.sysp = buffer->sysp;
+    }
+
+  return &buffer->dir;
+}
+
 /* The file_name_map structure holds a mapping of file names for a
    particular directory.  This mapping is read from the file named
    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
@@ -943,14 +946,14 @@ read_name_map (pfile, dirname)
 
   return map_list_ptr->map_list_map;
 }  
-
-/* Remap NAME based on the file_name_map (if any) for LOC. */
 
+/* Remap an unsimplified path NAME based on the file_name_map (if any)
+   for LOC.  */
 static char *
 remap_filename (pfile, name, loc)
      cpp_reader *pfile;
      char *name;
-     struct file_name_list *loc;
+     struct search_path *loc;
 {
   struct file_name_map *map;
   const char *from, *p;
@@ -958,12 +961,18 @@ remap_filename (pfile, name, loc)
 
   if (! loc->name_map)
     {
-      loc->name_map = read_name_map (pfile, loc->name ? loc->name : ".");
+      /* Get a null-terminated path.  */
+      char *dname = alloca (loc->len + 1);
+      memcpy (dname, loc->name, loc->len);
+      dname[loc->len] = '\0';
+
+      loc->name_map = read_name_map (pfile, dname);
       if (! loc->name_map)
 	return name;
     }
   
-  from = name + strlen (loc->name) + 1;
+  /* This works since NAME has not been simplified yet.  */
+  from = name + loc->len + 1;
   
   for (map = loc->name_map; map; map = map->map_next)
     if (!strcmp (map->map_from, from))
@@ -993,65 +1002,6 @@ remap_filename (pfile, name, loc)
   return name;
 }
 
-/* Given a path FNAME, extract the directory component and place it
-   onto the actual_dirs list.  Return a pointer to the allocated
-   file_name_list structure.  These structures are used to implement
-   current-directory "" include searching. */
-
-static struct file_name_list *
-actual_directory (pfile, fname)
-     cpp_reader *pfile;
-     const char *fname;
-{
-  char *last_slash, *dir;
-  size_t dlen;
-  struct file_name_list *x;
-  
-  dir = xstrdup (fname);
-  last_slash = strrchr (dir, '/');
-  if (last_slash)
-    {
-      if (last_slash == dir)
-        {
-	  dlen = 1;
-	  last_slash[1] = '\0';
-	}
-      else
-	{
-	  dlen = last_slash - dir;
-	  *last_slash = '\0';
-	}
-    }
-  else
-    {
-      free (dir);
-      dir = xstrdup (".");
-      dlen = 1;
-    }
-
-  if (dlen > pfile->max_include_len)
-    pfile->max_include_len = dlen;
-
-  for (x = pfile->actual_dirs; x; x = x->alloc)
-    if (!strcmp (x->name, dir))
-      {
-	free (dir);
-	return x;
-      }
-
-  /* Not found, make a new one. */
-  x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
-  x->name = dir;
-  x->nlen = dlen;
-  x->next = CPP_OPTION (pfile, quote_include);
-  x->alloc = pfile->actual_dirs;
-  x->sysp = pfile->buffer->sysp;
-  x->name_map = NULL;
-
-  pfile->actual_dirs = x;
-  return x;
-}
-
 /* Simplify a path name in place, deleting redundant components.  This
    reduces OS overhead and guarantees that equivalent paths compare
    the same (modulo symlinks).
@@ -1064,9 +1014,9 @@ actual_directory (pfile, fname)
    //quux		//quux  (POSIX allows leading // as a namespace escape)
 
    Guarantees no trailing slashes. All transforms reduce the length
-   of the string.
+   of the string.  Returns PATH;
  */
-void
+char *
 _cpp_simplify_pathname (path)
     char *path;
 {
@@ -1182,5 +1132,5 @@ _cpp_simplify_pathname (path)
     
     *to = '\0';
 
-    return;
+    return path;
 }
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.97.2.1
diff -u -p -r1.97.2.1 cpphash.h
--- cpphash.h	2001/03/02 00:43:56	1.97.2.1
+++ cpphash.h	2001/03/26 22:14:24
@@ -72,23 +72,23 @@ struct cpp_pool
   unsigned int locks;
 };
 
-/* List of directories to look for include files in. */
-struct file_name_list
+/* List of directories to look for include files in.  */
+struct search_path
 {
-  struct file_name_list *next;
-  struct file_name_list *alloc; /* for the cache of
-				   current directory entries */
-  char *name;
-  unsigned int nlen;
+  struct search_path *next;
+
+  /* NOTE: NAME may not be null terminated for the case of the current
+     file's directory!  */
+  const char *name;
+  unsigned int len;
   /* We use these to tell if the directory mentioned here is a duplicate
-     of an earlier directory on the search path. */
+     of an earlier directory on the search path.  */
   ino_t ino;
   dev_t dev;
-  /* If the following is nonzero, it is a C-language system include
-     directory.  */
+  /* Non-zero if it is a system include directory.  */
   int sysp;
-  /* Mapping of file names for this directory.
-     Only used on MS-DOS and related platforms. */
+  /* Mapping of file names for this directory.  Only used on MS-DOS
+     and related platforms.  */
   struct file_name_map *name_map;
 };
 
@@ -96,6 +96,9 @@ struct file_name_list
 enum mi_state {MI_FAILED = 0, MI_OUTSIDE};
 enum mi_ind {MI_IND_NONE = 0, MI_IND_NOT};
 
+/* #include types.  */
+enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
+
 typedef struct toklist toklist;
 struct toklist
 {
@@ -180,9 +183,6 @@ struct cpp_buffer
   /* Filename specified with #line command.  */
   const char *nominal_fname;
 
-  /* Actual directory of this file, used only for "" includes */
-  struct file_name_list *actual_dir;
-
   /* Pointer into the include table.  Used for include_next and
      to record control macros. */
   struct include_file *inc;
@@ -225,8 +225,16 @@ struct cpp_buffer
      containing files that matches the current status.  */
   unsigned char include_stack_listed;
 
+  /* Nonzero means that the directory to start searching for ""
+     include files has been calculated and stored in "dir" below.  */
+  unsigned char search_cached;
+
   /* Buffer type.  */
   ENUM_BITFIELD (cpp_buffer_type) type : 8;
+
+  /* The directory of the this buffer's file.  Its NAME member is not
+     allocated, so we don't need to worry about freeing it.  */
+  struct search_path dir;
 };
 
 /* A cpp_reader encapsulates the "state" of a pre-processor run.
@@ -297,10 +305,6 @@ struct cpp_reader
   /* Tree of other included files.  See cppfiles.c.  */
   struct splay_tree_s *all_include_files;
 
-  /* Chain of `actual directory' file_name_list entries, for ""
-     inclusion.  */
-  struct file_name_list *actual_dirs;
-
   /* Current maximum length of directory names in the search path
      for include files.  (Altered as we get more of them.)  */
   unsigned int max_include_len;
@@ -337,10 +341,6 @@ struct cpp_reader
   /* We're printed a warning recommending against using #import.  */
   unsigned char import_warning;
 
-  /* True after cpp_start_read completes.  Used to inhibit some
-     warnings while parsing the command line.  */
-  unsigned char done_initializing;
-
   /* True if we are skipping a failed conditional group.  */
   unsigned char skipping;
 
@@ -378,7 +378,6 @@ extern unsigned char _cpp_trigraph_map[U
 
 /* Macros.  */
 
-#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
 #define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
 #define CPP_IN_SYSTEM_HEADER(PFILE) \
   (CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->sysp)
@@ -412,10 +411,11 @@ extern cpp_hashnode *_cpp_lookup_with_ha
 /* In cppfiles.c */
 extern void _cpp_fake_include		PARAMS ((cpp_reader *, const char *));
 extern void _cpp_never_reread		PARAMS ((struct include_file *));
-extern void _cpp_simplify_pathname	PARAMS ((char *));
+extern char *_cpp_simplify_pathname	PARAMS ((char *));
 extern int _cpp_read_file		PARAMS ((cpp_reader *, const char *));
-extern void _cpp_execute_include	PARAMS ((cpp_reader *,
-						 const cpp_token *, int, int));
+extern int _cpp_execute_include		PARAMS ((cpp_reader *,
+						 const cpp_token *,
+						 enum include_type));
 extern int _cpp_compare_file_date       PARAMS ((cpp_reader *,
 						 const cpp_token *));
 extern void _cpp_report_missing_guards	PARAMS ((cpp_reader *));
Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppinit.c,v
retrieving revision 1.147.2.5
diff -u -p -r1.147.2.5 cppinit.c
--- cppinit.c	2001/03/02 19:08:03	1.147.2.5
+++ cppinit.c	2001/03/26 22:14:30
@@ -70,10 +70,10 @@ struct cpp_pending
 {
   struct pending_option *directive_head, *directive_tail;
 
-  struct file_name_list *quote_head, *quote_tail;
-  struct file_name_list *brack_head, *brack_tail;
-  struct file_name_list *systm_head, *systm_tail;
-  struct file_name_list *after_head, *after_tail;
+  struct search_path *quote_head, *quote_tail;
+  struct search_path *brack_head, *brack_tail;
+  struct search_path *systm_head, *systm_tail;
+  struct search_path *after_head, *after_tail;
 
   struct pending_option *imacros_head, *imacros_tail;
   struct pending_option *include_head, *include_tail;
@@ -100,10 +100,10 @@ static void init_library		PARAMS ((void)
 static void init_builtins		PARAMS ((cpp_reader *));
 static void append_include_chain	PARAMS ((cpp_reader *,
 						 char *, int, int));
-struct file_name_list * remove_dup_dir	PARAMS ((cpp_reader *,
-						 struct file_name_list *));
-struct file_name_list * remove_dup_dirs PARAMS ((cpp_reader *,
-						 struct file_name_list *));
+struct search_path * remove_dup_dir	PARAMS ((cpp_reader *,
+						 struct search_path *));
+struct search_path * remove_dup_dirs PARAMS ((cpp_reader *,
+						 struct search_path *));
 static void merge_include_chains	PARAMS ((cpp_reader *));
 static void do_includes			PARAMS ((cpp_reader *,
 						 struct pending_option *,
@@ -207,7 +207,7 @@ append_include_chain (pfile, dir, path, 
      int cxx_aware ATTRIBUTE_UNUSED;
 {
   struct cpp_pending *pend = CPP_OPTION (pfile, pending);
-  struct file_name_list *new;
+  struct search_path *new;
   struct stat st;
   unsigned int len;
 
@@ -232,9 +232,9 @@ append_include_chain (pfile, dir, path, 
   if (len > pfile->max_include_len)
     pfile->max_include_len = len;
 
-  new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
+  new = (struct search_path *) xmalloc (sizeof (struct search_path));
   new->name = dir;
-  new->nlen = len;
+  new->len = len;
   new->ino  = st.st_ino;
   new->dev  = st.st_dev;
   /* Both systm and after include file lists should be treated as system
@@ -250,7 +250,6 @@ append_include_chain (pfile, dir, path, 
     new->sysp = 0;
   new->name_map = NULL;
   new->next = NULL;
-  new->alloc = NULL;
 
   switch (path)
     {
@@ -263,18 +262,18 @@ append_include_chain (pfile, dir, path, 
 /* Handle a duplicated include path.  PREV is the link in the chain
    before the duplicate.  The duplicate is removed from the chain and
    freed.  Returns PREV.  */
-struct file_name_list *
+struct search_path *
 remove_dup_dir (pfile, prev)
      cpp_reader *pfile;
-     struct file_name_list *prev;
+     struct search_path *prev;
 {
-  struct file_name_list *cur = prev->next;
+  struct search_path *cur = prev->next;
 
   if (CPP_OPTION (pfile, verbose))
     fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name);
 
   prev->next = cur->next;
-  free (cur->name);
+  free ((PTR) cur->name);
   free (cur);
 
   return prev;
@@ -284,12 +283,12 @@ remove_dup_dir (pfile, prev)
    chain, or NULL if the chain is empty.  This algorithm is quadratic
    in the number of -I switches, which is acceptable since there
    aren't usually that many of them.  */
-struct file_name_list *
+struct search_path *
 remove_dup_dirs (pfile, head)
      cpp_reader *pfile;
-     struct file_name_list *head;
+     struct search_path *head;
 {
-  struct file_name_list *prev = NULL, *cur, *other;
+  struct search_path *prev = NULL, *cur, *other;
 
   for (cur = head; cur; cur = cur->next)
     {
@@ -318,7 +317,7 @@ static void
 merge_include_chains (pfile)
      cpp_reader *pfile;
 {
-  struct file_name_list *quote, *brack, *systm, *qtail;
+  struct search_path *quote, *brack, *systm, *qtail;
 
   struct cpp_pending *pend = CPP_OPTION (pfile, pending);
 
@@ -562,7 +561,7 @@ cpp_destroy (pfile)
      cpp_reader *pfile;
 {
   int result;
-  struct file_name_list *dir, *dirn;
+  struct search_path *dir, *dirn;
   cpp_context *context, *contextn;
 
   while (CPP_BUFFER (pfile) != NULL)
@@ -590,7 +589,7 @@ cpp_destroy (pfile)
   for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn)
     {
       dirn = dir->next;
-      free (dir->name);
+      free ((PTR) dir->name);
       free (dir);
     }
 
@@ -886,8 +885,15 @@ do_includes (pfile, p, scan)
 	 use the #include "" search path if cpp_read_file fails.  */
       if (CPP_OPTION (pfile, preprocessed))
 	cpp_error (pfile, "-include and -imacros cannot be used with -fpreprocessed");
-      else if (_cpp_read_file (pfile, p->arg) && scan)
-	cpp_scan_buffer_nooutput (pfile, 0);
+      else
+	{
+	  cpp_token header;
+	  header.type = CPP_STRING;
+	  header.val.str.text = (const unsigned char *) p->arg;
+	  header.val.str.len = strlen (p->arg);
+	  if (_cpp_execute_include (pfile, &header, IT_CMDLINE) && scan)
+	    cpp_scan_buffer_nooutput (pfile, 0);
+	}
       q = p->next;
       free (p);
       p = q;
@@ -913,7 +919,7 @@ cpp_start_read (pfile, fname)
   /* With -v, print the list of dirs to search.  */
   if (CPP_OPTION (pfile, verbose))
     {
-      struct file_name_list *l;
+      struct search_path *l;
       fprintf (stderr, _("#include \"...\" search starts here:\n"));
       for (l = CPP_OPTION (pfile, quote_include); l; l = l->next)
 	{
@@ -948,8 +954,6 @@ cpp_start_read (pfile, fname)
       free (p);
       p = q;
     }
-
-  pfile->done_initializing = 1;
 
   /* The -imacros files can be scanned now, but the -include files
      have to be pushed onto the buffer stack and processed later,
Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplex.c,v
retrieving revision 1.129.2.5
diff -u -p -r1.129.2.5 cpplex.c
--- cpplex.c	2001/03/07 01:19:55	1.129.2.5
+++ cpplex.c	2001/03/26 22:14:38
@@ -629,10 +629,11 @@ unescaped_terminator_p (pfile, dest)
 }
 
 /* Parses a string, character constant, or angle-bracketed header file
-   name.  Handles embedded trigraphs and escaped newlines.
+   name.  Handles embedded trigraphs and escaped newlines.  The stored
+   string is guaranteed NUL-terminated, but it is not guaranteed that
+   this is the first NUL since embedded NULs are preserved.
 
-   Multi-line strings are allowed, but they are deprecated within
-   directives.  */
+   Multi-line strings are allowed, but they are deprecated.  */
 static void
 parse_string (pfile, token, terminator)
      cpp_reader *pfile;
@@ -651,14 +652,21 @@ parse_string (pfile, token, terminator)
   for (;;)
     {
       if (buffer->cur == buffer->rlimit)
+	c = EOF;
+      else
+	c = *buffer->cur++;
+
+    have_char:
+      /* We need space for the terminating NUL.  */
+      if (dest >= limit)
+	limit = _cpp_next_chunk (pool, 0, &dest);
+
+      if (c == EOF)
 	{
-	  c = EOF;
 	  unterminated (pfile, terminator);
 	  break;
 	}
-      c = *buffer->cur++;
 
-    have_char:
       /* Handle trigraphs, escaped newlines etc.  */
       if (c == '?' || c == '\\')
 	c = skip_escaped_newlines (buffer, c);
@@ -690,8 +698,9 @@ parse_string (pfile, token, terminator)
 	  if (pfile->mlstring_pos.line == 0)
 	    pfile->mlstring_pos = pfile->lexer_pos;
 	      
-	  handle_newline (buffer, c);  /* Stores to read_ahead.  */
-	  c = '\n';
+	  c = handle_newline (buffer, c);
+	  *dest++ = '\n';
+	  goto have_char;
 	}
       else if (c == '\0')
 	{
@@ -699,25 +708,16 @@ parse_string (pfile, token, terminator)
 	    cpp_warning (pfile, "null character(s) preserved in literal");
 	}
 
-      /* No terminating null for strings - they could contain nulls.  */
-      if (dest >= limit)
-	limit = _cpp_next_chunk (pool, 0, &dest);
       *dest++ = c;
-
-      /* If we had a new line, the next character is in read_ahead.  */
-      if (c != '\n')
-	continue;
-      c = buffer->read_ahead;
-      if (c != EOF)
-	goto have_char;
     }
 
   /* Remember the next character.  */
   buffer->read_ahead = c;
+  *dest = '\0';
 
   token->val.str.text = POOL_FRONT (pool);
   token->val.str.len = dest - token->val.str.text;
-  POOL_COMMIT (pool, token->val.str.len);
+  POOL_COMMIT (pool, token->val.str.len + 1);
 }
 
 /* The stored comment includes the comment start and any terminator.  */
@@ -1457,26 +1457,6 @@ _cpp_equiv_tokens (a, b)
 
   return 0;
 }
-
-#if 0
-/* Compare two token lists.  */
-int
-_cpp_equiv_toklists (a, b)
-     const struct toklist *a, *b;
-{
-  unsigned int i, count;
-
-  count = a->limit - a->first;
-  if (count != (b->limit - b->first))
-    return 0;
-
-  for (i = 0; i < count; i++)
-    if (! _cpp_equiv_tokens (&a->first[i], &b->first[i]))
-      return 0;
-
-  return 1;
-}
-#endif
 
 /* Determine whether two tokens can be pasted together, and if so,
    what the resulting token is.  Returns CPP_EOF if the tokens cannot
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.239.2.2
diff -u -p -r1.239.2.2 cpplib.c
--- cpplib.c	2001/03/01 23:57:07	1.239.2.2
+++ cpplib.c	2001/03/26 22:14:41
@@ -95,6 +95,7 @@ static int  strtoul_for_line	PARAMS ((co
 					 unsigned long *));
 static void do_diagnostic	PARAMS ((cpp_reader *, enum error_type, int));
 static cpp_hashnode *lex_macro_node	PARAMS ((cpp_reader *));
+static void do_include_common	PARAMS ((cpp_reader *, enum include_type));
 static void do_pragma_once	PARAMS ((cpp_reader *));
 static void do_pragma_poison	PARAMS ((cpp_reader *));
 static void do_pragma_system_header	PARAMS ((cpp_reader *));
@@ -525,8 +526,9 @@ glue_header_name (pfile, header)
     cpp_error (pfile, "missing terminating > character");
   else
     {
-      token_mem = _cpp_pool_alloc (&pfile->ident_pool, total_len);
+      token_mem = _cpp_pool_alloc (&pfile->ident_pool, total_len + 1);
       memcpy (token_mem, buffer, total_len);
+      token_mem[total_len] = '\0';
 
       header->type = CPP_HEADER_NAME;
       header->flags &= ~PREV_WHITE;
@@ -584,22 +586,47 @@ parse_include (pfile, header)
   return 0;
 }
 
+/* Handle #include, #include_next and #import.  */
 static void
-do_include (pfile)
+do_include_common (pfile, type)
      cpp_reader *pfile;
+     enum include_type type;
 {
   cpp_token header;
 
   if (!parse_include (pfile, &header))
-    _cpp_execute_include (pfile, &header, 0, 0);
+    {
+      /* Prevent #include recursion.  */
+      if (pfile->buffer_stack_depth >= CPP_STACK_MAX)
+	cpp_fatal (pfile, "#include nested too deeply");
+      else if (pfile->context->prev)
+	cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
+      else
+	{
+	  /* For #include_next, if this is the primary source file,
+	     warn and use the normal search logic.  */
+	  if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
+	    {
+	      cpp_warning (pfile, "#include_next in primary source file");
+	      type = IT_INCLUDE;
+	    }
+
+	  _cpp_execute_include (pfile, &header, type);
+	}
+    }
 }
 
 static void
-do_import (pfile)
+do_include (pfile)
      cpp_reader *pfile;
 {
-  cpp_token header;
+  do_include_common (pfile, IT_INCLUDE);
+}
 
+static void
+do_import (pfile)
+     cpp_reader *pfile;
+{
   if (!pfile->import_warning && CPP_OPTION (pfile, warn_import))
     {
       pfile->import_warning = 1;
@@ -607,18 +634,14 @@ do_import (pfile)
 	   "#import is obsolete, use an #ifndef wrapper in the header file");
     }
 
-  if (!parse_include (pfile, &header))
-    _cpp_execute_include (pfile, &header, 1, 0);
+  do_include_common (pfile, IT_IMPORT);
 }
 
 static void
 do_include_next (pfile)
      cpp_reader *pfile;
 {
-  cpp_token header;
-
-  if (!parse_include (pfile, &header))
-    _cpp_execute_include (pfile, &header, 0, 1);
+  do_include_common (pfile, IT_INCLUDE_NEXT);
 }
 
 /* Subroutine of do_line.  Read possible flags after file name.  LAST
@@ -708,14 +731,10 @@ do_line (pfile)
   if (token.type == CPP_STRING)
     {
       char *fname;
-      unsigned int len;
+      unsigned int len = token.val.str.len + 1;
 
-      /* FIXME: memory leak.  */
-      len = token.val.str.len;
-      fname = xmalloc (len + 1);
+      fname = (char *) _cpp_pool_alloc (&pfile->ident_pool, len);
       memcpy (fname, token.val.str.text, len);
-      fname[len] = '\0';
-    
       _cpp_simplify_pathname (fname);
 
       /* Only accept flags for the # 55 form.  */
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.163.2.3
diff -u -p -r1.163.2.3 cpplib.h
--- cpplib.h	2001/03/07 01:19:55	1.163.2.3
+++ cpplib.h	2001/03/26 22:14:43
@@ -240,8 +240,8 @@ struct cpp_options
   const char *deps_file;
 
   /* Search paths for include files.  */
-  struct file_name_list *quote_include;	 /* First dir to search for "file" */
-  struct file_name_list *bracket_include;/* First dir to search for <file> */
+  struct search_path *quote_include;	/* "" */
+  struct search_path *bracket_include;  /* <> */
 
   /* Map between header names and file names, used only on DOS where
      file names are limited in length.  */
@@ -463,9 +463,7 @@ enum builtin_type
   BT_BASE_FILE,			/* `__BASE_FILE__' */
   BT_INCLUDE_LEVEL,		/* `__INCLUDE_LEVEL__' */
   BT_TIME,			/* `__TIME__' */
-  BT_STDC,			/* `__STDC__' */
-  BT_WEAK                       /* Whether or not G++ supports weak 
-				   symbols.  */
+  BT_STDC			/* `__STDC__' */
 };
 
 /* There is a slot in the hashnode for use by front ends when integrated
Index: cppmain.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmain.c,v
retrieving revision 1.61.2.1
diff -u -p -r1.61.2.1 cppmain.c
--- cppmain.c	2001/02/21 19:16:28	1.61.2.1
+++ cppmain.c	2001/03/26 22:14:45
@@ -347,7 +347,7 @@ cb_ident (pfile, str)
      const cpp_string * str;
 {
   maybe_print_line (cpp_get_line (pfile)->output_line);
-  fprintf (print.outf, "#ident \"%.*s\"\n", (int) str->len, str->text);
+  fprintf (print.outf, "#ident \"%s\"\n", str->text);
   print.lineno++;
 }
 
Index: mkdeps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/mkdeps.c,v
retrieving revision 1.11.4.1
diff -u -p -r1.11.4.1 mkdeps.c
--- mkdeps.c	2001/02/14 10:02:35	1.11.4.1
+++ mkdeps.c	2001/03/26 22:14:47
@@ -191,7 +191,7 @@ deps_add_default_target (d, tgt)
 #ifndef OBJECT_SUFFIX
 # define OBJECT_SUFFIX ".o"
 #endif
-      char *start = basename (tgt);
+      char *start = lbasename (tgt);
       char *o = (char *) alloca (strlen (start) + strlen (OBJECT_SUFFIX) + 1);
       char *suffix;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]