diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 77a6af1b6452b1fd54e14d134bdac817e5166a59..de601425437bdf369e51129a1a1d2445c9f77b6b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2000-07-15  Zack Weinberg  <zack@wolery.cumb.org>
+
+	* cpphash.c (save_expansion): Clear PREV_WHITE on tokens
+	immediately following a paste operator.
+	* cppinit.c (sort_options): New function (only for HOST_EBCDIC).
+	(cpp_reader_init): Call it, if HOST_EBCDIC.
+	(cpp_handle_options): Do not sort option list here.
+	(handle_option): Rename to cpp_handle_option and export.
+	* cpplex.c (cpp_scan_buffer_nooutput, cpp_scan_buffer): Use
+	_cpp_get_token directly.
+	(cpp_scan_line): Return 0 at EOF, 1 otherwise.
+	* cpplib.c (cpp_push_buffer): Don't set new->lineno to 1.
+	* cpplib.h: Prototype cpp_handle_option.  Update prototype of
+	cpp_scan_line.
+
 2000-07-15  Richard Henderson  <rth@cygnus.com>
 
 	* fold-const.c (extract_muldiv): Don't optimize past an unsigned
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index 8c4be523e4b7dac3cf8e60c53909c1b9acc9565c..b7f3944c4e5b8e9b0a8c29ca9eb88e80d59dc3eb 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -576,6 +576,11 @@ save_expansion (pfile, info)
 	    dest->flags = token[-1].flags | STRINGIFY_ARG;
 	  else
 	    dest->flags = token->flags;  /* Particularly PREV_WHITE.  */
+	  /* Turn off PREV_WHITE if we immediately follow a paste.
+	     That way, even if the paste turns out to be illegal, there
+	     will be no space between the two tokens in the output.  */
+	  if (token[-1].type == CPP_PASTE)
+	    dest->flags &= ~PREV_WHITE;
 	  dest++;
 	  continue;
 
@@ -602,6 +607,8 @@ save_expansion (pfile, info)
 	  dest->val.str.text = buf;
 	  buf += dest->val.str.len;
 	}
+      if (token[-1].type == CPP_PASTE)
+	dest->flags &= ~PREV_WHITE;
       dest++;
     }
 
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 476d396f170600987021fee78420a135f3abe309..c31b2fda3663e0a90d15fc20155d15455209d3c0 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -106,14 +106,14 @@ static void merge_include_chains	PARAMS ((cpp_reader *));
 
 static void initialize_dependency_output PARAMS ((cpp_reader *));
 static void initialize_standard_includes PARAMS ((cpp_reader *));
-static void new_pending_directive		PARAMS ((struct cpp_pending *,
+static void new_pending_directive	PARAMS ((struct cpp_pending *,
 						 const char *,
 						 cl_directive_handler));
 #ifdef HOST_EBCDIC
 static int opt_comp			PARAMS ((const void *, const void *));
+static void sort_options		PARAMS ((void));
 #endif
 static int parse_option			PARAMS ((const char *));
-static int handle_option		PARAMS ((cpp_reader *, int, char **));
 
 /* Fourth argument to append_include_chain: chain to use */
 enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
@@ -408,6 +408,10 @@ void
 cpp_reader_init (pfile)
      cpp_reader *pfile;
 {
+#ifdef HOST_EBCDIC
+  sort_options ();
+#endif
+
   memset ((char *) pfile, 0, sizeof (cpp_reader));
 
   pfile->token_buffer_size = 200;
@@ -1063,6 +1067,22 @@ static const struct cl_option cl_options[] =
 #undef DEF_OPT
 #undef COMMAND_LINE_OPTIONS
 
+#ifdef HOST_EBCDIC
+static void
+sort_options (void)
+{
+  static int opts_sorted = 0;
+
+  if (!opts_sorted)
+    {
+      opts_sorted = 1;
+      /* For non-ASCII hosts, the array needs to be sorted at runtime */
+      qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
+    }
+}
+#endif
+
+
 /* Perform a binary search to find which, if any, option the given
    command-line matches.  Returns its index in the option array,
    negative on failure.  Complications arise since some options can be
@@ -1131,8 +1151,8 @@ parse_option (input)
    Can be called multiple times, to handle multiple sets of options.
    Returns number of strings consumed.  */
 
-static int
-handle_option (pfile, argc, argv)
+int
+cpp_handle_option (pfile, argc, argv)
      cpp_reader *pfile;
      int argc;
      char **argv;
@@ -1637,20 +1657,9 @@ cpp_handle_options (pfile, argc, argv)
   int i;
   int strings_processed;
 
-#ifdef HOST_EBCDIC
-  static int opts_sorted = 0;
-
-  if (!opts_sorted)
-    {
-      opts_sorted = 1;
-      /* For non-ASCII hosts, the array needs to be sorted at runtime */
-      qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
-    }
-#endif
-
   for (i = 0; i < argc; i += strings_processed)
     {
-      strings_processed = handle_option (pfile, argc - i, argv + i);
+      strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
       if (strings_processed == 0)
 	break;
     }
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index fa5b638f3d704b15889d4e4e9da7918eaf9e8821..32aaaab3e70c78900ffd757823e95bafb7976402 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -412,22 +412,30 @@ void
 cpp_scan_buffer_nooutput (pfile)
      cpp_reader *pfile;
 {
-  unsigned int old_written = CPP_WRITTEN (pfile);
   cpp_buffer *stop = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
+  const cpp_token *token;
 
+  /* In no-output mode, we can ignore everything but directives.  */
   for (;;)
     {
-      /* In no-output mode, we can ignore everything but directives.  */
-      const cpp_token *token = cpp_get_token (pfile);
+      token = _cpp_get_token (pfile);
+
       if (token->type == CPP_EOF)
 	{
 	  cpp_pop_buffer (pfile);
 	  if (CPP_BUFFER (pfile) == stop)
 	    break;
 	}
+
+      if (token->type == CPP_HASH && token->flags & BOL
+	  && pfile->token_list.directive)
+	{
+	  process_directive (pfile, token);
+	  continue;
+	}
+
       _cpp_skip_rest_of_line (pfile);
     }
-  CPP_SET_WRITTEN (pfile, old_written);
 }
 
 /* Scan until CPP_BUFFER (pfile) is exhausted, writing output to PRINT.  */
@@ -441,12 +449,13 @@ cpp_scan_buffer (pfile, print)
 
   for (;;)
     {
-      token = cpp_get_token (pfile);
+      token = _cpp_get_token (pfile);
       if (token->type == CPP_EOF)
 	{
 	  cpp_pop_buffer (pfile);
 	  if (CPP_BUFFER (pfile) == stop)
 	    return;
+
 	  cpp_output_tokens (pfile, print, CPP_BUF_LINE (CPP_BUFFER (pfile)));
 	  prev = 0;
 	  continue;
@@ -454,22 +463,33 @@ cpp_scan_buffer (pfile, print)
 
       if (token->flags & BOL)
 	{
+	  if (token->type == CPP_HASH && pfile->token_list.directive)
+	    {
+	      process_directive (pfile, token);
+	      continue;
+	    }
+
 	  cpp_output_tokens (pfile, print, pfile->token_list.line);
 	  prev = 0;
 	}
 
-      output_token (pfile, token, prev);
+      if (token->type != CPP_PLACEMARKER)
+	output_token (pfile, token, prev);
+
       prev = token;
     }
 }
 
 /* Scan a single line of the input into the token_buffer.  */
-void
+int
 cpp_scan_line (pfile)
      cpp_reader *pfile;
 {
   const cpp_token *token, *prev = 0;
 
+  if (pfile->buffer == NULL)
+    return 0;
+
   do
     {
       token = cpp_get_token (pfile);
@@ -479,11 +499,18 @@ cpp_scan_line (pfile)
 	  break;
 	}
 
+      /* If the last token on a line results from a macro expansion,
+	 the check below will fail to stop us from proceeding to the
+	 next line - so make sure we stick in a newline, at least.  */
+      if (token->flags & BOL)
+	CPP_PUTC (pfile, '\n');
+
       output_token (pfile, token, prev);
       prev = token;
     }
   while (pfile->cur_context > 0
 	 || pfile->contexts[0].posn < pfile->contexts[0].count);
+  return 1;
 }
 
 /* Helper routine used by parse_include, which can't see spell_token.
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index e55f9555ef72b39a1449207ea3bb73e13519c1f3..aaf55a0d3c522a96066d57b83b0d0f303e56d61b 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -1520,7 +1520,6 @@ cpp_push_buffer (pfile, buffer, length)
   new->line_base = new->buf = new->cur = buffer;
   new->rlimit = buffer + length;
   new->prev = buf;
-  new->lineno = 1;
 
   CPP_BUFFER (pfile) = new;
   return new;
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index 88c06485199e131bc07788199f94219c51183eb5..500b5e25a0ef22ef652e8be800a2f6fe59b851bc 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -636,6 +636,7 @@ struct cpp_hashnode
 };
 
 extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
+extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
 extern void cpp_reader_init PARAMS ((cpp_reader *));
 extern cpp_printer *cpp_printer_init PARAMS ((cpp_reader *, cpp_printer *));
 extern int cpp_start_read PARAMS ((cpp_reader *, cpp_printer *, const char *));
@@ -688,7 +689,7 @@ extern cpp_buffer *cpp_push_buffer	PARAMS ((cpp_reader *,
 extern cpp_buffer *cpp_pop_buffer	PARAMS ((cpp_reader *));
 extern void cpp_scan_buffer		PARAMS ((cpp_reader *, cpp_printer *));
 extern void cpp_scan_buffer_nooutput	PARAMS ((cpp_reader *));
-extern void cpp_scan_line		PARAMS ((cpp_reader *));
+extern int cpp_scan_line		PARAMS ((cpp_reader *));
 extern int cpp_ideq			PARAMS ((const cpp_token *,
 						 const char *));