cppfiles.c (ENABLE_VALGRIND_CHECKING, [...]): Remove.
authorNeil Booth <neil@daikokuya.co.uk>
Sat, 19 Apr 2003 00:22:51 +0000 (00:22 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Sat, 19 Apr 2003 00:22:51 +0000 (00:22 +0000)
* cppfiles.c (ENABLE_VALGRIND_CHECKING, VALGRIND_DISCARD,
MMAP_THRESHOLD, TEST_THRESHOLD, SHOULD_MMAP): Remove.
(struct include_file): Remove fefcnt, mapped members.
(open_file, stack_include_file, _cpp_pop_file_buffer): Disable caching.
(read_include_file): Don't use mmap, terminate buffers in '\r'.
(purge_cache): Don't use munmap.
* cpphash.h (CPP_BUF_COLUMN): Update.
(lexer_state): Remove lexing_comment.
(struct _cpp_line_note): New.
(struct cpp_buffer): New members cur_note, notes_used, notes_cap,
next_line and need_line.  Remove col_adjust and saved_flags.
(_cpp_process_line_notes, _cpp_clean_line, _cpp_get_fresh_line,
_cpp_skip_block_comment, scan_out_logical_line): New.
(_cpp_init_mbchar): Remove.
* cppinit.c (init_library): Remove call to _cpp_init_mbchar.
(cpp_read_main_file): Set line to 1 earlier.
(post_options): -traditional-cpp doesn't want trigraphs.
* cpplex.c (MULTIBYTE_CHARS): Remove code predicated on this.
(add_line_note, _cpp_clean_line, _cpp_process_line_notes,
_cpp_get_fresh_line): New.
(handle_newline, skip_escaped_newlines, trigraph_p,
continue_after_nul, _cpp_init_mbchar): Remove.
(get_effective_char): Update.
(_cpp_skip_block_comment): Rename from skip_block_comment, simplify.
(skip_line_comment): Simplify.
(skip_whitespace, parse_identifier, parse_slow, parse_number,
parse_string): Update.
(cpp_lex_direct): Use clean lines and process line notes.  Update.
(cpp_interpret_charconst): No MULTIBYTE_CHARS.
* cpplib.c (prepare_directive_trad): Call scan_out_logical_line
directly.
(_cpp_handle_directive): Don't set saved_flags.
(run_directive, destringize_and_run, cpp_define, cpp_define_builtin,
cpp_undef, handle_assertion, cpp_push_buffer): Update.
(_cpp_pop_buffer): Free notes.
* cppmacro.c (builtin_macro, paste_tokens): \n terminate buffer.
* cpppch.c (cpp_read_state): \n terminate buffer.
* cpptrad.c (skip_escaped_newlines, handle_newline): Remove.
(copy_comment): Use _cpp_skip_block_comment.
(skip_whitespace, lex_identifier, _cpp_read_logical_line_trad):
Simplify.
(_cpp_overlay_buffer, _cpp_remove_overlay, push_replacement_text,
save_replacement_text): Update.
(scan_out_logical_line): Update to use clean lines and process
line notes.
* fix-header.c (read_scan_file): Update.
testsuite:
* gcc.dg/cpp/_Pragma4.c: Remove stray space.
* gcc.dg/cpp/trad/escaped-eof.c: Correct line number.

From-SVN: r65808

13 files changed:
gcc/ChangeLog
gcc/cppfiles.c
gcc/cpphash.h
gcc/cppinit.c
gcc/cpplex.c
gcc/cpplib.c
gcc/cppmacro.c
gcc/cpppch.c
gcc/cpptrad.c
gcc/fix-header.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/_Pragma4.c
gcc/testsuite/gcc.dg/cpp/trad/escaped-eof.c

index 1b9bb92353783e087313374c8be09e86d9c7afe5..978e98ab7947ed926b078b7e735245ce943efb02 100644 (file)
@@ -1,3 +1,52 @@
+2003-04-19  Neil Booth  <neil@daikokuya.co.uk>
+
+       * cppfiles.c (ENABLE_VALGRIND_CHECKING, VALGRIND_DISCARD,
+       MMAP_THRESHOLD, TEST_THRESHOLD, SHOULD_MMAP): Remove.
+       (struct include_file): Remove fefcnt, mapped members.
+       (open_file, stack_include_file, _cpp_pop_file_buffer): Disable caching.
+       (read_include_file): Don't use mmap, terminate buffers in '\r'.
+       (purge_cache): Don't use munmap.
+       * cpphash.h (CPP_BUF_COLUMN): Update.
+       (lexer_state): Remove lexing_comment.
+       (struct _cpp_line_note): New.
+       (struct cpp_buffer): New members cur_note, notes_used, notes_cap,
+       next_line and need_line.  Remove col_adjust and saved_flags.
+       (_cpp_process_line_notes, _cpp_clean_line, _cpp_get_fresh_line,
+       _cpp_skip_block_comment, scan_out_logical_line): New.
+       (_cpp_init_mbchar): Remove.
+       * cppinit.c (init_library): Remove call to _cpp_init_mbchar.
+       (cpp_read_main_file): Set line to 1 earlier.
+       (post_options): -traditional-cpp doesn't want trigraphs.
+       * cpplex.c (MULTIBYTE_CHARS): Remove code predicated on this.
+       (add_line_note, _cpp_clean_line, _cpp_process_line_notes,
+       _cpp_get_fresh_line): New.
+       (handle_newline, skip_escaped_newlines, trigraph_p,
+       continue_after_nul, _cpp_init_mbchar): Remove.
+       (get_effective_char): Update.
+       (_cpp_skip_block_comment): Rename from skip_block_comment, simplify.
+       (skip_line_comment): Simplify.
+       (skip_whitespace, parse_identifier, parse_slow, parse_number,
+       parse_string): Update.
+       (cpp_lex_direct): Use clean lines and process line notes.  Update.
+       (cpp_interpret_charconst): No MULTIBYTE_CHARS.
+       * cpplib.c (prepare_directive_trad): Call scan_out_logical_line
+       directly.
+       (_cpp_handle_directive): Don't set saved_flags.
+       (run_directive, destringize_and_run, cpp_define, cpp_define_builtin,
+       cpp_undef, handle_assertion, cpp_push_buffer): Update.
+       (_cpp_pop_buffer): Free notes.
+       * cppmacro.c (builtin_macro, paste_tokens): \n terminate buffer.
+       * cpppch.c (cpp_read_state): \n terminate buffer.
+       * cpptrad.c (skip_escaped_newlines, handle_newline): Remove.
+       (copy_comment): Use _cpp_skip_block_comment.
+       (skip_whitespace, lex_identifier, _cpp_read_logical_line_trad):
+       Simplify.
+       (_cpp_overlay_buffer, _cpp_remove_overlay, push_replacement_text,
+       save_replacement_text): Update.
+       (scan_out_logical_line): Update to use clean lines and process
+       line notes.
+       * fix-header.c (read_scan_file): Update.
+
 2003-04-18  Douglas B Rupp  <rupp@gnat.com>
 
        * unwind-dw2-fde.c (__register_frame_info_bases): Check for
index 1ff34ff00846831f8ae736fcc266b44cfe3d4b60..4b8643d744532599fae4832e7ba3dbfdcbcf07bd 100644 (file)
@@ -30,47 +30,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "intl.h"
 #include "mkdeps.h"
 #include "splay-tree.h"
-#ifdef ENABLE_VALGRIND_CHECKING
-# ifdef HAVE_MEMCHECK_H
-# include <memcheck.h>
-# else
-# include <valgrind.h>
-# endif
-#else
-/* Avoid #ifdef:s when we can help it.  */
-#define VALGRIND_DISCARD(x)
-#endif
-
-#ifdef HAVE_MMAP_FILE
-# include <sys/mman.h>
-# ifndef MMAP_THRESHOLD
-#  define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file.  */
-# endif
-# if MMAP_THRESHOLD
-#  define TEST_THRESHOLD(size, pagesize) \
-     (size / pagesize >= MMAP_THRESHOLD && (size % pagesize) != 0)
-   /* Use mmap if the file is big enough to be worth it (controlled
-      by MMAP_THRESHOLD) and if we can safely count on there being
-      at least one readable NUL byte after the end of the file's
-      contents.  This is true for all tested operating systems when
-      the file size is not an exact multiple of the page size.  */
-#  ifndef __CYGWIN__
-#   define SHOULD_MMAP(size, pagesize) TEST_THRESHOLD (size, pagesize)
-#  else
-#   define WIN32_LEAN_AND_MEAN
-#   include <windows.h>
-    /* Cygwin can't correctly emulate mmap under Windows 9x style systems so
-       disallow use of mmap on those systems.  Windows 9x does not zero fill
-       memory at EOF and beyond, as required.  */
-#   define SHOULD_MMAP(size, pagesize) ((GetVersion() & 0x80000000) \
-                                       ? 0 : TEST_THRESHOLD (size, pagesize))
-#  endif
-# endif
-
-#else  /* No MMAP_FILE */
-#  undef MMAP_THRESHOLD
-#  define MMAP_THRESHOLD 0
-#endif
 
 #ifndef O_BINARY
 # define O_BINARY 0
@@ -102,8 +61,6 @@ struct include_file {
   int fd;                      /* fd open on file (short term storage only) */
   int err_no;                  /* errno obtained if opening a file failed */
   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 pch;           /* 0: file not known to be a PCH.
                                   1: file is a PCH 
                                      (on return from find_include_file).
@@ -278,7 +235,7 @@ open_file (pfile, filename)
     return file;
 
   /* Don't reopen one which is already loaded.  */
-  if (file->buffer != NULL)
+  if (0 && file->buffer != NULL)
     return file;
 
   /* We used to open files in nonblocking mode, but that caused more
@@ -446,7 +403,7 @@ stack_include_file (pfile, inc)
     }
 
   /* Not in cache?  */
-  if (! inc->buffer)
+  if (1 || ! inc->buffer)
     {
       if (read_include_file (pfile, inc))
        {
@@ -471,7 +428,6 @@ stack_include_file (pfile, inc)
   fp = cpp_push_buffer (pfile, inc->buffer, inc->st.st_size,
                        /* from_stage3 */ CPP_OPTION (pfile, preprocessed), 0);
   fp->inc = inc;
-  fp->inc->refcnt++;
 
   /* Initialize controlling macro state.  */
   pfile->mi_valid = true;
@@ -507,9 +463,6 @@ read_include_file (pfile, inc)
 {
   ssize_t size, offset, count;
   uchar *buf;
-#if MMAP_THRESHOLD
-  static int pagesize = -1;
-#endif
 
   if (S_ISREG (inc->st.st_mode))
     {
@@ -528,25 +481,6 @@ read_include_file (pfile, inc)
        }
       size = inc->st.st_size;
 
-      inc->mapped = 0;
-#if MMAP_THRESHOLD
-      if (pagesize == -1)
-       pagesize = getpagesize ();
-
-      if (SHOULD_MMAP (size, pagesize))
-       {
-         buf = (uchar *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
-         if (buf == (uchar *) -1)
-           goto perror_fail;
-
-         /* We must tell Valgrind that the byte at buf[size] is actually
-            readable.  Discard the handle to avoid handle leak.  */
-         VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (buf + size, 1));
-
-         inc->mapped = 1;
-       }
-      else
-#endif
        {
          buf = (uchar *) xmalloc (size + 1);
          offset = 0;
@@ -567,8 +501,8 @@ read_include_file (pfile, inc)
                }
              offset += count;
            }
-         /* The lexer requires that the buffer be NUL-terminated.  */
-         buf[size] = '\0';
+         /* The lexer requires that the buffer be \n-terminated.  */
+         buf[size] = '\n';
        }
     }
   else if (S_ISBLK (inc->st.st_mode))
@@ -600,8 +534,8 @@ read_include_file (pfile, inc)
       if (offset + 1 < size)
        buf = xrealloc (buf, offset + 1);
 
-      /* The lexer requires that the buffer be NUL-terminated.  */
-      buf[offset] = '\0';
+      /* The lexer requires that the buffer be \n-terminated.  */
+      buf[offset] = '\n';
       inc->st.st_size = offset;
     }
 
@@ -614,26 +548,14 @@ read_include_file (pfile, inc)
   return 1;
 }
 
-/* Drop INC's buffer from memory, if we are unlikely to need it again.  */
+/* Drop INC's buffer from memory.  */
 static void
 purge_cache (inc)
      struct include_file *inc;
 {
   if (inc->buffer)
     {
-#if MMAP_THRESHOLD
-      if (inc->mapped)
-       {
-         /* Undo the previous annotation for the
-            known-zero-byte-after-mmap.  Discard the handle to avoid
-            handle leak.  */
-         VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (inc->buffer
-                                                   + inc->st.st_size, 1));
-         munmap ((PTR) inc->buffer, inc->st.st_size);
-       }
-      else
-#endif
-       free ((PTR) inc->buffer);
+      free ((PTR) inc->buffer);
       inc->buffer = NULL;
     }
 }
@@ -929,9 +851,7 @@ _cpp_pop_file_buffer (pfile, inc)
   /* Invalidate control macros in the #including file.  */
   pfile->mi_valid = false;
 
-  inc->refcnt--;
-  if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
-    purge_cache (inc);
+  purge_cache (inc);
 }
 
 /* Returns the first place in the include chain to start searching for
index bc0d099599bfc3e2efed4099ac62197f2b6539ce..4b5cd499cf00a06424134b7f6d1be7a62b29b4c3 100644 (file)
@@ -45,7 +45,7 @@ typedef unsigned char uchar;
 
 #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
 #define CPP_BUFFER(PFILE) ((PFILE)->buffer)
-#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
+#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base)
 #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
 
 /* Maximum nesting of cpp_buffers.  We use a static limit, partly for
@@ -212,9 +212,6 @@ struct lexer_state
      all directives apart from #define.  */
   unsigned char save_comments;
 
-  /* Nonzero if we're mid-comment.  */
-  unsigned char lexing_comment;
-
   /* Nonzero if lexing __VA_ARGS__ is valid.  */
   unsigned char va_args_ok;
 
@@ -240,17 +237,37 @@ struct spec_nodes
   cpp_hashnode *n__VA_ARGS__;          /* C99 vararg macros */
 };
 
+typedef struct _cpp_line_note _cpp_line_note;
+struct _cpp_line_note
+{
+  /* Location in the clean line the note refers to.  */
+  const uchar *pos;
+
+  /* Type of note.  */
+  enum { NOTE_ESC_NL = 0,
+        NOTE_ESC_SPACE_NL,
+        NOTE_TRIGRAPH,
+        NOTE_NEWLINE } type;
+};
+
 /* Represents the contents of a file cpplib has read in.  */
 struct cpp_buffer
 {
-  const unsigned char *cur;     /* current position */
-  const unsigned char *backup_to; /* if peeked character is not wanted */
-  const unsigned char *rlimit; /* end of valid data */
-  const unsigned char *line_base; /* start of current line */
+  const uchar *cur;            /* Current location.  */
+  const uchar *line_base;      /* Start of current physical line.  */
+  const uchar *next_line;      /* Start of to-be-cleaned logical line.  */
+  
+  const uchar *buf;            /* Entire character buffer.  */
+  const uchar *rlimit;         /* Writable byte at end of file.  */
+
+  _cpp_line_note *notes;       /* Array of notes.  */
+  unsigned int cur_note;       /* Next note to process.  */
+  unsigned int notes_used;     /* Number of notes.  */
+  unsigned int notes_cap;      /* Size of allocated array.  */
 
   struct cpp_buffer *prev;
 
-  const unsigned char *buf;     /* Entire character buffer.  */
+  const unsigned char *backup_to; /* Soon to die.  */
 
   /* Pointer into the include table; non-NULL if this is a file
      buffer.  Used for include_next and to record control macros.  */
@@ -260,15 +277,8 @@ struct cpp_buffer
      Used to prohibit unmatched #endif (etc) in an include file.  */
   struct if_stack *if_stack;
 
-  /* Token column position adjustment owing to tabs in whitespace.  */
-  unsigned int col_adjust;
-
-  /* Contains PREV_WHITE and/or AVOID_LPASTE.  */
-  unsigned char saved_flags;
-
-  /* Because of the way the lexer works, -Wtrigraphs can sometimes
-     warn twice for the same trigraph.  This helps prevent that.  */
-  const unsigned char *last_Wtrigraphs;
+  /* True if we need to get the next clean line.  */
+  bool need_line;
 
   /* True if we have already warned about C++ comments in this file.
      The warning happens only for C89 extended mode with -pedantic on,
@@ -503,13 +513,16 @@ extern bool _cpp_parse_expr               PARAMS ((cpp_reader *));
 extern struct op *_cpp_expand_op_stack PARAMS ((cpp_reader *));
 
 /* In cpplex.c */
+extern void _cpp_process_line_notes    PARAMS ((cpp_reader *, int));
+extern void _cpp_clean_line            PARAMS ((cpp_reader *));
+extern bool _cpp_get_fresh_line                PARAMS ((cpp_reader *));
+extern bool _cpp_skip_block_comment    PARAMS ((cpp_reader *));
 extern cpp_token *_cpp_temp_token      PARAMS ((cpp_reader *));
 extern const cpp_token *_cpp_lex_token PARAMS ((cpp_reader *));
 extern cpp_token *_cpp_lex_direct      PARAMS ((cpp_reader *));
 extern int _cpp_equiv_tokens           PARAMS ((const cpp_token *,
                                                 const cpp_token *));
 extern void _cpp_init_tokenrun         PARAMS ((tokenrun *, unsigned int));
-extern void _cpp_init_mbchar           PARAMS ((void));
 
 /* In cppinit.c.  */
 extern void _cpp_maybe_push_include_file PARAMS ((cpp_reader *));
@@ -529,6 +542,7 @@ extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason,
 extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
 
 /* In cpptrad.c.  */
+extern bool scan_out_logical_line PARAMS ((cpp_reader *, cpp_macro *));
 extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *));
 extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
                                         size_t));
index 376d72e9e588ad3fe8d3d62eabf0a4ac41c2f0fa..74679c0111b234b29142f9b048a8d92bb918f039 100644 (file)
@@ -125,8 +125,6 @@ init_library ()
         we were compiled with a compiler that supports C99 designated
         initializers.  */
       init_trigraph_map ();
-
-      _cpp_init_mbchar ();
     }
 }
 
@@ -167,7 +165,6 @@ cpp_create_reader (lang, table)
   /* Initialize the line map.  Start at logical line 1, so we can use
      a line number of zero for special states.  */
   init_line_maps (&pfile->line_maps);
-  pfile->line = 1;
 
   /* Initialize lexer state.  */
   pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
@@ -454,6 +451,7 @@ cpp_read_main_file (pfile, fname)
     }
 
   /* Open the main input file.  */
+  pfile->line = 1;
   if (!_cpp_read_file (pfile, fname))
     return NULL;
 
@@ -556,7 +554,11 @@ post_options (pfile)
       CPP_OPTION (pfile, traditional) = 0;
     }
 
-  /* Traditional CPP does not accurately track column information.  */
   if (CPP_OPTION (pfile, traditional))
-    CPP_OPTION (pfile, show_column) = 0;
+    {
+      /* Traditional CPP does not accurately track column information.  */
+      CPP_OPTION (pfile, show_column) = 0;
+      CPP_OPTION (pfile, trigraphs) = 0;
+      CPP_OPTION (pfile, warn_trigraphs) = 0;
+    }
 }
index 93e04b8b5293f8b7dba5620887a72b7e22906745..930e887948d230df652d4e11ab5b0a8b5b4f98b3 100644 (file)
@@ -4,7 +4,6 @@
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
    Broken out to separate file, Zack Weinberg, Mar 2000
-   Single-pass line tokenization by Neil Booth, April 2000
 
 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
@@ -27,11 +26,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "cpplib.h"
 #include "cpphash.h"
 
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif
-
 /* Tokens with SPELL_STRING store their spelling in the token list,
    and it's length in the token->val.name.len.  */
 enum spell_type
@@ -63,24 +57,19 @@ static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE };
 #define TOKEN_NAME(token) (token_spellings[(token)->type].name)
 #define BACKUP() do {buffer->cur = buffer->backup_to;} while (0)
 
-static void handle_newline PARAMS ((cpp_reader *));
-static cppchar_t skip_escaped_newlines PARAMS ((cpp_reader *));
+static void add_line_note PARAMS ((cpp_buffer *, const uchar *, unsigned int));
 static cppchar_t get_effective_char PARAMS ((cpp_reader *));
 
-static int skip_block_comment PARAMS ((cpp_reader *));
 static int skip_line_comment PARAMS ((cpp_reader *));
-static void adjust_column PARAMS ((cpp_reader *));
-static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
+static void skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
 static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
 static uchar *parse_slow PARAMS ((cpp_reader *, const uchar *, int,
                                  unsigned int *));
 static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
 static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *));
 static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
-static bool trigraph_p PARAMS ((cpp_reader *));
 static void save_comment PARAMS ((cpp_reader *, cpp_token *, const uchar *,
                                  cppchar_t));
-static bool continue_after_nul PARAMS ((cpp_reader *));
 static int name_p PARAMS ((cpp_reader *, const cpp_string *));
 static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **,
                                   const unsigned char *, cppchar_t *));
@@ -89,15 +78,6 @@ static tokenrun *next_tokenrun PARAMS ((tokenrun *));
 static unsigned int hex_digit_value PARAMS ((unsigned int));
 static _cpp_buff *new_buff PARAMS ((size_t));
 
-/* Change to the native locale for multibyte conversions.  */
-void
-_cpp_init_mbchar ()
-{
-#ifdef MULTIBYTE_CHARS
-  setlocale (LC_CTYPE, "");
-  GET_ENVIRONMENT (literal_codeset, "LANG");
-#endif
-}
 
 /* Utility routine:
 
@@ -114,132 +94,158 @@ cpp_ideq (token, string)
   return !ustrcmp (NODE_NAME (token->val.node), (const uchar *) string);
 }
 
-/* Call when meeting a newline, assumed to be in buffer->cur[-1].
-   Returns with buffer->cur pointing to the character immediately
-   following the newline (combination).  */
+/* Record a note TYPE at byte POS into the current cleaned logical
+   line.  */
 static void
-handle_newline (pfile)
-     cpp_reader *pfile;
+add_line_note (buffer, pos, type)
+     cpp_buffer *buffer;
+     const uchar *pos;
+     unsigned int type;
 {
-  cpp_buffer *buffer = pfile->buffer;
-
-  /* Handle CR-LF and LF-CR.  Most other implementations (e.g. java)
-     only accept CR-LF; maybe we should fall back to that behavior?  */
-  if (buffer->cur[-1] + buffer->cur[0] == '\r' + '\n')
-    buffer->cur++;
+  if (buffer->notes_used == buffer->notes_cap)
+    {
+      buffer->notes_cap = buffer->notes_cap * 2 + 200;
+      buffer->notes = (_cpp_line_note *)
+       xrealloc (buffer->notes, buffer->notes_cap * sizeof (_cpp_line_note));
+    }
 
-  buffer->line_base = buffer->cur;
-  buffer->col_adjust = 0;
-  pfile->line++;
+  buffer->notes[buffer->notes_used].pos = pos;
+  buffer->notes[buffer->notes_used].type = type;
+  buffer->notes_used++;
 }
 
-/* Subroutine of skip_escaped_newlines; called when a 3-character
-   sequence beginning with "??" is encountered.  buffer->cur points to
-   the second '?'.
-
-   Warn if necessary, and returns true if the sequence forms a
-   trigraph and the trigraph should be honored.  */
-static bool
-trigraph_p (pfile)
+/* Returns with a logical line that contains no escaped newlines or
+   trigraphs.  This is a time-critical inner loop.  */
+void
+_cpp_clean_line (pfile)
      cpp_reader *pfile;
 {
-  cpp_buffer *buffer = pfile->buffer;
-  cppchar_t from_char = buffer->cur[1];
-  bool accept;
-
-  if (!_cpp_trigraph_map[from_char])
-    return false;
+  cpp_buffer *buffer;
+  const uchar *s;
+  uchar c, *d, *p;
 
-  accept = CPP_OPTION (pfile, trigraphs);
+  buffer = pfile->buffer;
+  buffer->cur_note = buffer->notes_used = 0;
+  buffer->cur = buffer->line_base = buffer->next_line;
+  buffer->need_line = false;
+  s = buffer->next_line - 1;
 
-  /* Don't warn about trigraphs in comments.  */
-  if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
+  if (!buffer->from_stage3)
     {
-      if (accept)
-       cpp_error_with_line (pfile, DL_WARNING,
-                            pfile->line, CPP_BUF_COL (buffer) - 1,
-                            "trigraph ??%c converted to %c",
-                            (int) from_char,
-                            (int) _cpp_trigraph_map[from_char]);
-      else if (buffer->cur != buffer->last_Wtrigraphs)
+      d = (uchar *) s;
+
+      for (;;)
        {
-         buffer->last_Wtrigraphs = buffer->cur;
-         cpp_error_with_line (pfile, DL_WARNING,
-                              pfile->line, CPP_BUF_COL (buffer) - 1,
-                              "trigraph ??%c ignored", (int) from_char);
+         c = *++s;
+         *++d = c;
+
+         if (c == '\n' || c == '\r')
+           {
+                 /* Handle DOS line endings.  */
+             if (c == '\r' && s != buffer->rlimit && s[1] == '\n')
+               s++;
+             if (s == buffer->rlimit)
+               break;
+
+             /* Escaped?  */
+             p = d;
+             while (p != buffer->next_line && is_nvspace (p[-1]))
+               p--;
+             if (p == buffer->next_line || p[-1] != '\\')
+               break;
+
+             add_line_note (buffer, p - 1,
+                            p != d ? NOTE_ESC_SPACE_NL: NOTE_ESC_NL);
+             d = p - 2;
+             buffer->next_line = p - 1;
+           }
+         else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
+           {
+             /* Add a note regardless, for the benefit of -Wtrigraphs.  */
+             add_line_note (buffer, d, NOTE_TRIGRAPH);
+             if (CPP_OPTION (pfile, trigraphs))
+               {
+                 *d = _cpp_trigraph_map[s[2]];
+                 s += 2;
+               }
+           }
        }
     }
+  else
+    {
+      do
+       s++;
+      while (*s != '\n' && *s != '\r');
+      d = (uchar *) s;
+
+      /* Handle DOS line endings.  */
+      if (*s == '\r' && s != buffer->rlimit && s[1] == '\n')
+       s++;
+    }
 
-  return accept;
+  *d = '\n';
+  add_line_note (buffer, d + 1, NOTE_NEWLINE);
+  buffer->next_line = s + 1;
 }
 
-/* Skips any escaped newlines introduced by '?' or a '\\', assumed to
-   lie in buffer->cur[-1].  Returns the next byte, which will be in
-   buffer->cur[-1].  This routine performs preprocessing stages 1 and
-   2 of the ISO C standard.  */
-static cppchar_t
-skip_escaped_newlines (pfile)
+/* Process the notes created by add_line_note as far as the current
+   location.  */
+void
+_cpp_process_line_notes (pfile, in_comment)
      cpp_reader *pfile;
+     int in_comment;
 {
   cpp_buffer *buffer = pfile->buffer;
-  cppchar_t next = buffer->cur[-1];
 
-  /* Only do this if we apply stages 1 and 2.  */
-  if (!buffer->from_stage3)
+  for (;;)
     {
-      const unsigned char *saved_cur;
-      cppchar_t next1;
+      _cpp_line_note *note = &buffer->notes[buffer->cur_note];
+      unsigned int col;
 
-      do
-       {
-         if (next == '?')
-           {
-             if (buffer->cur[0] != '?' || !trigraph_p (pfile))
-               break;
-
-             /* Translate the trigraph.  */
-             next = _cpp_trigraph_map[buffer->cur[1]];
-             buffer->cur += 2;
-             if (next != '\\')
-               break;
-           }
+      if (note->pos > buffer->cur)
+       break;
 
-         if (buffer->cur == buffer->rlimit)
-           break;
+      buffer->cur_note++;
+      col = CPP_BUF_COLUMN (buffer, note->pos + 1);
 
-         /* We have a backslash, and room for at least one more
-            character.  Skip horizontal whitespace.  */
-         saved_cur = buffer->cur;
-         do
-           next1 = *buffer->cur++;
-         while (is_nvspace (next1) && buffer->cur < buffer->rlimit);
+      switch (note->type)
+       {
+       case NOTE_NEWLINE:
+         /* This note is a kind of sentinel we should never reach.  */
+         abort ();
 
-         if (!is_vspace (next1))
+       case NOTE_TRIGRAPH:
+         if (!in_comment && CPP_OPTION (pfile, warn_trigraphs))
            {
-             buffer->cur = saved_cur;
-             break;
+             if (CPP_OPTION (pfile, trigraphs))
+               cpp_error_with_line (pfile, DL_WARNING, pfile->line, col,
+                                    "trigraph converted to %c",
+                                    (int) note->pos[0]);
+             else
+               cpp_error_with_line (pfile, DL_WARNING, pfile->line, col,
+                                    "trigraph ??%c ignored",
+                                    (int) note->pos[2]);
            }
+         break;
 
-         if (saved_cur != buffer->cur - 1
-             && !pfile->state.lexing_comment)
-           cpp_error (pfile, DL_WARNING,
-                      "backslash and newline separated by space");
-
-         handle_newline (pfile);
-         buffer->backup_to = buffer->cur;
-         if (buffer->cur == buffer->rlimit)
+       case NOTE_ESC_SPACE_NL:
+         if (!in_comment)
+           cpp_error_with_line (pfile, DL_WARNING, pfile->line, col,
+                                "backslash and newline separated by space");
+         /* Fall through... */
+       case NOTE_ESC_NL:
+         if (buffer->next_line > buffer->rlimit)
            {
-             cpp_error (pfile, DL_PEDWARN,
-                        "backslash-newline at end of file");
-             next = EOF;
+             cpp_error_with_line (pfile, DL_PEDWARN, pfile->line, col,
+                                  "backslash-newline at end of file");
+             /* Prevent "no newline at end of file" warning.  */
+             buffer->next_line = buffer->rlimit;
            }
-         else
-           next = *buffer->cur++;
+
+         buffer->line_base = note->pos;
+         pfile->line++;
        }
-      while (next == '\\' || next == '?');
     }
-
-  return next;
 }
 
 /* Obtain the next character, after trigraph conversion and skipping
@@ -251,42 +257,34 @@ static cppchar_t
 get_effective_char (pfile)
      cpp_reader *pfile;
 {
-  cppchar_t next;
   cpp_buffer *buffer = pfile->buffer;
 
   buffer->backup_to = buffer->cur;
-  next = *buffer->cur++;
-  if (__builtin_expect (next == '?' || next == '\\', 0))
-    next = skip_escaped_newlines (pfile);
-
-  return next;
+  return *buffer->cur++;
 }
 
 /* Skip a C-style block comment.  We find the end of the comment by
    seeing if an asterisk is before every '/' we encounter.  Returns
    nonzero if comment terminated by EOF, zero otherwise.  */
-static int
-skip_block_comment (pfile)
+bool
+_cpp_skip_block_comment (pfile)
      cpp_reader *pfile;
 {
   cpp_buffer *buffer = pfile->buffer;
-  cppchar_t c = EOF, prevc = EOF;
+  cppchar_t c;
 
-  pfile->state.lexing_comment = 1;
-  while (buffer->cur != buffer->rlimit)
-    {
-      prevc = c, c = *buffer->cur++;
+  if (*buffer->cur == '/')
+    buffer->cur++;
 
-      /* FIXME: For speed, create a new character class of characters
-        of interest inside block comments.  */
-      if (c == '?' || c == '\\')
-       c = skip_escaped_newlines (pfile);
+  for (;;)
+    {
+      c = *buffer->cur++;
 
       /* People like decorating comments with '*', so check for '/'
         instead for efficiency.  */
       if (c == '/')
        {
-         if (prevc == '*')
+         if (buffer->cur[-2] == '*')
            break;
 
          /* Warn about potential nested comments, but not if the '/'
@@ -298,14 +296,18 @@ skip_block_comment (pfile)
                                 pfile->line, CPP_BUF_COL (buffer),
                                 "\"/*\" within comment");
        }
-      else if (is_vspace (c))
-       handle_newline (pfile);
-      else if (c == '\t')
-       adjust_column (pfile);
+      else if (c == '\n')
+       {
+         buffer->cur--;
+         _cpp_process_line_notes (pfile, true);
+         if (buffer->next_line >= buffer->rlimit)
+           return true;
+         _cpp_clean_line (pfile);
+         pfile->line++;
+       }
     }
 
-  pfile->state.lexing_comment = 0;
-  return c != '/' || prevc != '*';
+  return false;
 }
 
 /* Skip a C++ line comment, leaving buffer->cur pointing to the
@@ -317,72 +319,16 @@ skip_line_comment (pfile)
 {
   cpp_buffer *buffer = pfile->buffer;
   unsigned int orig_line = pfile->line;
-  cppchar_t c;
-#ifdef MULTIBYTE_CHARS
-  wchar_t wc;
-  int char_len;
-#endif
-
-  pfile->state.lexing_comment = 1;
-#ifdef MULTIBYTE_CHARS
-  /* Reset multibyte conversion state.  */
-  (void) local_mbtowc (NULL, NULL, 0);
-#endif
-  do
-    {
-      if (buffer->cur == buffer->rlimit)
-       goto at_eof;
-
-#ifdef MULTIBYTE_CHARS
-      char_len = local_mbtowc (&wc, (const char *) buffer->cur,
-                              buffer->rlimit - buffer->cur);
-      if (char_len == -1)
-       {
-         cpp_error (pfile, DL_WARNING,
-                    "ignoring invalid multibyte character");
-         char_len = 1;
-         c = *buffer->cur++;
-       }
-      else
-       {
-         buffer->cur += char_len;
-         c = wc;
-       }
-#else
-      c = *buffer->cur++;
-#endif
-      if (c == '?' || c == '\\')
-       c = skip_escaped_newlines (pfile);
-    }
-  while (!is_vspace (c));
 
-  /* Step back over the newline, except at EOF.  */
-  buffer->cur--;
- at_eof:
+  while (*buffer->cur != '\n')
+    buffer->cur++;
 
-  pfile->state.lexing_comment = 0;
+  _cpp_process_line_notes (pfile, true);
   return orig_line != pfile->line;
 }
 
-/* pfile->buffer->cur is one beyond the \t character.  Update
-   col_adjust so we track the column correctly.  */
+/* Skips whitespace, saving the next non-whitespace character.  */
 static void
-adjust_column (pfile)
-     cpp_reader *pfile;
-{
-  cpp_buffer *buffer = pfile->buffer;
-  unsigned int col = CPP_BUF_COL (buffer) - 1; /* Zero-based column.  */
-
-  /* Round it up to multiple of the tabstop, but subtract 1 since the
-     tab itself occupies a character position.  */
-  buffer->col_adjust += (CPP_OPTION (pfile, tabstop)
-                        - col % CPP_OPTION (pfile, tabstop)) - 1;
-}
-
-/* Skips whitespace, saving the next non-whitespace character.
-   Adjusts pfile->col_adjust to account for tabs.  Without this,
-   tokens might be assigned an incorrect column.  */
-static int
 skip_whitespace (pfile, c)
      cpp_reader *pfile;
      cppchar_t c;
@@ -393,15 +339,11 @@ skip_whitespace (pfile, c)
   do
     {
       /* Horizontal space always OK.  */
-      if (c == ' ')
+      if (c == ' ' || c == '\t')
        ;
-      else if (c == '\t')
-       adjust_column (pfile);
       /* Just \f \v or \0 left.  */
       else if (c == '\0')
        {
-         if (buffer->cur - 1 == buffer->rlimit)
-           return 0;
          if (!warned)
            {
              cpp_error (pfile, DL_WARNING, "null character(s) ignored");
@@ -420,7 +362,6 @@ skip_whitespace (pfile, c)
   while (is_nvspace (c));
 
   buffer->cur--;
-  return 1;
 }
 
 /* See if the characters of a number token are valid in a name (no
@@ -461,7 +402,7 @@ parse_identifier (pfile)
     cur++;
 
   /* Check for slow-path cases.  */
-  if (*cur == '?' || *cur == '\\' || *cur == '$')
+  if (*cur == '$')
     {
       unsigned int len;
 
@@ -532,8 +473,6 @@ parse_slow (pfile, cur, number_p, plen)
     {
       /* Potential escaped newline?  */
       buffer->backup_to = buffer->cur - 1;
-      if (c == '?' || c == '\\')
-       c = skip_escaped_newlines (pfile);
 
       if (!is_idchar (c))
        {
@@ -590,7 +529,7 @@ parse_number (pfile, number, leading_period)
     cur++;
 
   /* Check for slow-path cases.  */
-  if (*cur == '?' || *cur == '\\' || *cur == '$')
+  if (*cur == '$')
     number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len);
   else
     {
@@ -648,18 +587,10 @@ parse_string (pfile, token, terminator)
   unsigned char *dest, *limit;
   cppchar_t c;
   bool warned_nulls = false;
-#ifdef MULTIBYTE_CHARS
-  wchar_t wc;
-  int char_len;
-#endif
 
   dest = BUFF_FRONT (pfile->u_buff);
   limit = BUFF_LIMIT (pfile->u_buff);
 
-#ifdef MULTIBYTE_CHARS
-  /* Reset multibyte conversion state.  */
-  (void) local_mbtowc (NULL, NULL, 0);
-#endif
   for (;;)
     {
       /* We need room for another char, possibly the terminating NUL.  */
@@ -671,41 +602,19 @@ parse_string (pfile, token, terminator)
          limit = BUFF_LIMIT (pfile->u_buff);
        }
 
-#ifdef MULTIBYTE_CHARS
-      char_len = local_mbtowc (&wc, (const char *) buffer->cur,
-                              buffer->rlimit - buffer->cur);
-      if (char_len == -1)
-       {
-         cpp_error (pfile, DL_WARNING,
-                    "ignoring invalid multibyte character");
-         char_len = 1;
-         c = *buffer->cur++;
-       }
-      else
-       {
-         buffer->cur += char_len;
-         c = wc;
-       }
-#else
       c = *buffer->cur++;
-#endif
-
-      /* Handle trigraphs, escaped newlines etc.  */
-      if (c == '?' || c == '\\')
-       c = skip_escaped_newlines (pfile);
 
       if (c == terminator)
        {
          if (unescaped_terminator_p (pfile, dest))
            break;
        }
-      else if (is_vspace (c))
+      else if (c == '\n')
        {
          /* No string literal may extend over multiple lines.  In
             assembly language, suppress the error except for <>
             includes.  This is a kludge around not knowing where
             comments are.  */
-       unterminated:
          if (CPP_OPTION (pfile, lang) != CLK_ASM || terminator == '>')
            cpp_error (pfile, DL_ERROR, "missing terminating %c character",
                       (int) terminator);
@@ -714,8 +623,6 @@ parse_string (pfile, token, terminator)
        }
       else if (c == '\0')
        {
-         if (buffer->cur - 1 == buffer->rlimit)
-           goto unterminated;
          if (!warned_nulls)
            {
              warned_nulls = true;
@@ -723,14 +630,6 @@ parse_string (pfile, token, terminator)
                         "null character(s) preserved in literal");
            }
        }
-#ifdef MULTIBYTE_CHARS
-      if (char_len > 1)
-       {
-         for ( ; char_len > 0; --char_len)
-           *dest++ = (*buffer->cur - char_len);
-       }
-      else
-#endif
        *dest++ = c;
     }
 
@@ -890,55 +789,55 @@ _cpp_lex_token (pfile)
   return result;
 }
 
-/* A NUL terminates the current buffer.  For ISO preprocessing this is
-   EOF, but for traditional preprocessing it indicates we need a line
-   refill.  Returns TRUE to continue preprocessing a new buffer, FALSE
-   to return a CPP_EOF to the caller.  */
-static bool
-continue_after_nul (pfile)
+/* Returns true if a fresh line has been loaded.  */
+bool
+_cpp_get_fresh_line (pfile)
      cpp_reader *pfile;
 {
-  cpp_buffer *buffer = pfile->buffer;
-  bool more = false;
+  /* We can't get a new line until we leave the current directive.  */
+  if (pfile->state.in_directive)
+    return false;
 
-  buffer->saved_flags = BOL;
-  if (CPP_OPTION (pfile, traditional))
+  for (;;)
     {
-      if (pfile->state.in_directive)
-       return false;
+      cpp_buffer *buffer = pfile->buffer;
 
-      _cpp_remove_overlay (pfile);
-      more = _cpp_read_logical_line_trad (pfile);
-      _cpp_overlay_buffer (pfile, pfile->out.base,
-                          pfile->out.cur - pfile->out.base);
-      pfile->line = pfile->out.first_line;
-    }
-  else
-    {
-      /* Stop parsing arguments with a CPP_EOF.  When we finally come
-        back here, do the work of popping the buffer.  */
-      if (!pfile->state.parsing_args)
+      if (!buffer->need_line)
+       return true;
+
+      if (buffer->next_line < buffer->rlimit)
        {
-         if (buffer->cur != buffer->line_base)
-           {
-             /* Non-empty files should end in a newline.  Don't warn
-                for command line and _Pragma buffers.  */
-             if (!buffer->from_stage3)
-               cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
-             handle_newline (pfile);
-           }
+         _cpp_clean_line (pfile);
+         return true;
+       }
 
-         /* Similarly, finish an in-progress directive with CPP_EOF
-            before popping the buffer.  */
-         if (!pfile->state.in_directive && buffer->prev)
-           {
-             more = !buffer->return_at_eof;
-             _cpp_pop_buffer (pfile);
-           }
+      /* First, get out of parsing arguments state.  */
+      if (pfile->state.parsing_args)
+       return false;
+
+      /* End of buffer.  Non-empty files should end in a newline.  */
+      if (buffer->buf != buffer->rlimit
+         && buffer->next_line > buffer->rlimit
+         && !buffer->from_stage3)
+       {
+         /* Only warn once.  */
+         buffer->next_line = buffer->rlimit;
+         cpp_error_with_line (pfile, DL_PEDWARN, pfile->line - 1,
+                              CPP_BUF_COLUMN (buffer, buffer->cur),
+                              "no newline at end of file");
+       }
+      if (buffer->return_at_eof)
+       {
+         buffer->return_at_eof = false;
+         return false;
        }
-    }
 
-  return more;
+      if (!buffer->prev)
+       return false;
+
+      _cpp_pop_buffer (pfile);
+    }
 }
 
 #define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \
@@ -973,74 +872,49 @@ _cpp_lex_direct (pfile)
   cpp_token *result = pfile->cur_token++;
 
  fresh_line:
+  result->flags = 0;
+  if (pfile->buffer->need_line)
+    {
+      if (!_cpp_get_fresh_line (pfile))
+       {
+         result->type = CPP_EOF;
+         return result;
+       }
+      if (!pfile->keep_tokens)
+       {
+         pfile->cur_run = &pfile->base_run;
+         result = pfile->base_run.base;
+         pfile->cur_token = result + 1;
+       }
+      result->flags = BOL;
+      if (pfile->state.parsing_args == 2)
+       result->flags |= PREV_WHITE;
+    }
   buffer = pfile->buffer;
-  result->flags = buffer->saved_flags;
-  buffer->saved_flags = 0;
  update_tokens_line:
   result->line = pfile->line;
 
  skipped_white:
+  if (buffer->cur >= buffer->notes[buffer->cur_note].pos
+      && !pfile->overlaid_buffer)
+    {
+      _cpp_process_line_notes (pfile, false);
+      result->line = pfile->line;
+    }
   c = *buffer->cur++;
   result->col = CPP_BUF_COLUMN (buffer, buffer->cur);
 
- trigraph:
   switch (c)
     {
     case ' ': case '\t': case '\f': case '\v': case '\0':
       result->flags |= PREV_WHITE;
-      if (skip_whitespace (pfile, c))
-       goto skipped_white;
-
-      /* End of buffer.  */
-      buffer->cur--;
-      if (continue_after_nul (pfile))
-       goto fresh_line;
-      result->type = CPP_EOF;
-      break;
+      skip_whitespace (pfile, c);
+      goto skipped_white;
 
-    case '\n': case '\r':
-      handle_newline (pfile);
-      buffer->saved_flags = BOL;
-      if (! pfile->state.in_directive)
-       {
-         if (pfile->state.parsing_args == 2)
-           buffer->saved_flags |= PREV_WHITE;
-         if (!pfile->keep_tokens)
-           {
-             pfile->cur_run = &pfile->base_run;
-             result = pfile->base_run.base;
-             pfile->cur_token = result + 1;
-           }
-         goto fresh_line;
-       }
-      result->type = CPP_EOF;
-      break;
-
-    case '?':
-    case '\\':
-      /* These could start an escaped newline, or '?' a trigraph.  Let
-        skip_escaped_newlines do all the work.  */
-      {
-       unsigned int line = pfile->line;
-
-       c = skip_escaped_newlines (pfile);
-       if (line != pfile->line)
-         {
-           buffer->cur--;
-           /* We had at least one escaped newline of some sort.
-              Update the token's line and column.  */
-           goto update_tokens_line;
-         }
-      }
-
-      /* We are either the original '?' or '\\', or a trigraph.  */
-      if (c == '?')
-       result->type = CPP_QUERY;
-      else if (c == '\\')
-       goto random_char;
-      else
-       goto trigraph;
-      break;
+    case '\n':
+      pfile->line++;
+      buffer->need_line = true;
+      goto fresh_line;
 
     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
@@ -1100,7 +974,7 @@ _cpp_lex_direct (pfile)
 
       if (c == '*')
        {
-         if (skip_block_comment (pfile))
+         if (_cpp_skip_block_comment (pfile))
            cpp_error (pfile, DL_ERROR, "unterminated comment");
        }
       else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments)
@@ -1331,6 +1205,7 @@ _cpp_lex_direct (pfile)
     case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break;
     case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); break;
 
+    case '?': result->type = CPP_QUERY; break;
     case '~': result->type = CPP_COMPL; break;
     case ',': result->type = CPP_COMMA; break;
     case '(': result->type = CPP_OPEN_PAREN; break;
@@ -1349,7 +1224,6 @@ _cpp_lex_direct (pfile)
        goto start_ident;
       /* Fall through...  */
 
-    random_char:
     default:
       result->type = CPP_OTHER;
       result->val.c = c;
@@ -1927,10 +1801,6 @@ cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
   cppchar_t c, mask, result = 0;
   bool unsigned_p;
 
-#ifdef MULTIBYTE_CHARS
-  (void) local_mbtowc (NULL, NULL, 0);
-#endif
-
   /* Width in bits.  */
   if (token->type == CPP_CHAR)
     {
@@ -1952,25 +1822,7 @@ cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
 
   while (str < limit)
     {
-#ifdef MULTIBYTE_CHARS
-      wchar_t wc;
-      int char_len;
-
-      char_len = local_mbtowc (&wc, (const char *)str, limit - str);
-      if (char_len == -1)
-       {
-         cpp_error (pfile, DL_WARNING,
-                    "ignoring invalid multibyte character");
-         c = *str++;
-       }
-      else
-       {
-         str += char_len;
-         c = wc;
-       }
-#else
       c = *str++;
-#endif
 
       if (c == '\\')
        c = cpp_parse_escape (pfile, &str, limit, token->type == CPP_WCHAR);
index 7d2d965247721a14c283af342e7538f386236833..bb983b04a292682705db9593ced632eb1df30da2 100644 (file)
@@ -295,7 +295,7 @@ prepare_directive_trad (pfile)
                                    || pfile->directive == &dtable[T_ELIF]);
       if (no_expand)
        pfile->state.prevent_expansion++;
-      _cpp_read_logical_line_trad (pfile);
+      scan_out_logical_line (pfile, NULL);
       if (no_expand)
        pfile->state.prevent_expansion--;
       pfile->state.skipping = was_skipping;
@@ -451,13 +451,12 @@ _cpp_handle_directive (pfile, indented)
       /* Restore state when within macro args.  */
       pfile->state.parsing_args = 2;
       pfile->state.prevent_expansion = 1;
-      pfile->buffer->saved_flags |= PREV_WHITE;
     }
   return skip;
 }
 
 /* Directive handler wrapper used by the command line option
-   processor.  */
+   processor.  BUF is \n terminated.  */
 static void
 run_directive (pfile, dir_no, buf, count)
      cpp_reader *pfile;
@@ -471,8 +470,11 @@ run_directive (pfile, dir_no, buf, count)
   if (dir_no == T_PRAGMA)
     pfile->buffer->inc = pfile->buffer->prev->inc;
   start_directive (pfile);
-  /* We don't want a leading # to be interpreted as a directive.  */
-  pfile->buffer->saved_flags = 0;
+
+  /* This is a short-term fix to prevent a leading '#' being
+     interpreted as a directive.  */
+  _cpp_clean_line (pfile);
+
   pfile->directive = &dtable[dir_no];
   if (CPP_OPTION (pfile, traditional))
     prepare_directive_trad (pfile);
@@ -1378,7 +1380,7 @@ destringize_and_run (pfile, in)
        src++;
       *dest++ = *src++;
     }
-  *dest = '\0';
+  *dest = '\n';
 
   /* Ugh; an awful kludge.  We are really not set up to be lexing
      tokens when in the middle of a macro expansion.  Use a new
@@ -1904,7 +1906,7 @@ cpp_define (pfile, str)
       buf[count++] = ' ';
       buf[count++] = '1';
     }
-  buf[count] = '\0';
+  buf[count] = '\n';
 
   run_directive (pfile, T_DEFINE, buf, count);
 }
@@ -1915,7 +1917,11 @@ _cpp_define_builtin (pfile, str)
      cpp_reader *pfile;
      const char *str;
 {
-  run_directive (pfile, T_DEFINE, str, strlen (str));
+  size_t len = strlen (str);
+  char *buf = alloca (len + 1);
+  memcpy (buf, str, len);
+  buf[len] = '\n';
+  run_directive (pfile, T_DEFINE, buf, len);
 }
 
 /* Process MACRO as if it appeared as the body of an #undef.  */
@@ -1924,7 +1930,11 @@ cpp_undef (pfile, macro)
      cpp_reader *pfile;
      const char *macro;
 {
-  run_directive (pfile, T_UNDEF, macro, strlen (macro));
+  size_t len = strlen (macro);
+  char *buf = alloca (len + 1);
+  memcpy (buf, macro, len);
+  buf[len] = '\n';
+  run_directive (pfile, T_UNDEF, buf, len);
 }
 
 /* Process the string STR as if it appeared as the body of a #assert.  */
@@ -1955,18 +1965,18 @@ handle_assertion (pfile, str, type)
   size_t count = strlen (str);
   const char *p = strchr (str, '=');
 
+  /* Copy the entire option so we can modify it.  Change the first
+     "=" in the string to a '(', and tack a ')' on the end.  */
+  char *buf = (char *) alloca (count + 2);
+
+  memcpy (buf, str, count);
   if (p)
     {
-      /* Copy the entire option so we can modify it.  Change the first
-        "=" in the string to a '(', and tack a ')' on the end.  */
-      char *buf = (char *) alloca (count + 2);
-
-      memcpy (buf, str, count);
       buf[p - str] = '(';
       buf[count++] = ')';
-      buf[count] = '\0';
-      str = buf;
     }
+  buf[count] = '\n';
+  str = buf;
 
   run_directive (pfile, type, str, count);
 }
@@ -2028,15 +2038,14 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
   /* Clears, amongst other things, if_stack and mi_cmacro.  */
   memset (new, 0, sizeof (cpp_buffer));
 
-  new->line_base = new->buf = new->cur = buffer;
+  new->next_line = new->buf = buffer;
   new->rlimit = buffer + len;
-  new->from_stage3 = from_stage3 || CPP_OPTION (pfile, traditional);
+  new->from_stage3 = from_stage3;
   new->prev = pfile->buffer;
   new->return_at_eof = return_at_eof;
-  new->saved_flags = BOL;
+  new->need_line = true;
 
   pfile->buffer = new;
-
   return new;
 }
 
@@ -2062,6 +2071,8 @@ _cpp_pop_buffer (pfile)
   /* _cpp_do_file_change expects pfile->buffer to be the new one.  */
   pfile->buffer = buffer->prev;
 
+  free (buffer->notes);
+
   /* Free the buffer object now; we may want to push a new buffer
      in _cpp_push_next_include_file.  */
   obstack_free (&pfile->buffer_ob, buffer);
index 94fa8583a8ad27618545c9dd2e01073fef049ed7..0898dac8cd197563d28050e8369a5e3431865bec 100644 (file)
@@ -265,6 +265,8 @@ builtin_macro (pfile, node)
      cpp_hashnode *node;
 {
   const uchar *buf;
+  size_t len;
+  char *nbuf;
 
   if (node->value.builtin == BT_PRAGMA)
     {
@@ -278,14 +280,13 @@ builtin_macro (pfile, node)
     }
 
   buf = _cpp_builtin_macro_text (pfile, node);
+  len = ustrlen (buf);
+  nbuf = alloca (len + 1);
+  memcpy (nbuf, buf, len);
+  nbuf[len]='\n';
 
-  cpp_push_buffer (pfile, buf, ustrlen (buf), /* from_stage3 */ true, 1);
-
-  /* Tweak the column number the lexer will report.  */
-  pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1;
-
-  /* We don't want a leading # to be interpreted as a directive.  */
-  pfile->buffer->saved_flags = 0;
+  cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true, 1);
+  _cpp_clean_line (pfile);
 
   /* Set pfile->cur_token as required by _cpp_lex_direct.  */
   pfile->cur_token = _cpp_temp_token (pfile);
@@ -445,15 +446,10 @@ paste_tokens (pfile, plhs, rhs)
   if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
     *end++ = ' ';
   end = cpp_spell_token (pfile, rhs, end);
-  *end = '\0';
+  *end = '\n';
 
   cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true, 1);
-
-  /* Tweak the column number the lexer will report.  */
-  pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1;
-
-  /* We don't want a leading # to be interpreted as a directive.  */
-  pfile->buffer->saved_flags = 0;
+  _cpp_clean_line (pfile);
 
   /* Set pfile->cur_token as required by _cpp_lex_direct.  */
   pfile->cur_token = _cpp_temp_token (pfile);
index 388a7532c11a1142f22965b56bb8d35502567edc..602711a427ed97c6ccf84473d44433a5e945a82b 100644 (file)
@@ -708,7 +708,7 @@ cpp_read_state (r, name, f, data)
 
       if (fread (defn, 1, m.definition_length, f) != m.definition_length)
        goto error;
-      defn[m.definition_length] = '\0';
+      defn[m.definition_length] = '\n';
       
       h = cpp_lookup (r, defn, m.name_length);
 
@@ -722,6 +722,7 @@ cpp_read_state (r, name, f, data)
                               m.definition_length - m.name_length, 
                               true, 1) != NULL)
            {
+             _cpp_clean_line (r);
              if (!_cpp_create_definition (r, h))
                abort ();
              _cpp_pop_buffer (r);
index 92c4ee3d52204242da139ef0d3b5c351f2a0e78f..f2f94f6d045752da53ebd25fcdf68843e57eac9b 100644 (file)
@@ -81,14 +81,10 @@ enum ls {ls_none = 0,               /* Normal state.  */
 /* Lexing TODO: Maybe handle space in escaped newlines.  Stop cpplex.c
    from recognizing comments and directives during its lexing pass.  */
 
-static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
-static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
-                                                  const uchar *));
 static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *,
                                             int));
 static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
 static const uchar *copy_comment PARAMS ((cpp_reader *, const uchar *, int));
-static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *));
 static void check_output_buffer PARAMS ((cpp_reader *, size_t));
 static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
 static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
@@ -125,43 +121,6 @@ check_output_buffer (pfile, n)
     }
 }
 
-/* To be called whenever a newline character is encountered in the
-   input file, at CUR.  Handles DOS, Mac and Unix ends of line, and
-   increments pfile->line.
-
-   Returns a pointer the character after the newline sequence.  */
-static const uchar *
-handle_newline (pfile, cur)
-     cpp_reader *pfile;
-     const uchar *cur;
-{
-  pfile->line++;
-  if (cur[0] + cur[1] == '\r' + '\n')
-    cur++;
-  return cur + 1;
-}
-
-/* CUR points to any character in the current context, not necessarily
-   a backslash.  Advances CUR until all escaped newlines are skipped,
-   and returns the new position without updating the context.
-
-   Warns if a file buffer ends in an escaped newline.  */
-static const uchar *
-skip_escaped_newlines (pfile, cur)
-     cpp_reader *pfile;
-     const uchar *cur;
-{
-  const uchar *orig_cur = cur;
-
-  while (*cur == '\\' && is_vspace (cur[1]))
-    cur = handle_newline (pfile, cur + 1);
-
-  if (cur != orig_cur && cur == RLIMIT (pfile->context) && pfile->buffer->inc)
-    cpp_error (pfile, DL_PEDWARN, "backslash-newline at end of file");
-
-  return cur;
-}
-
 /* CUR points to the asterisk introducing a comment in the current
    context.  IN_DEFINE is true if we are in the replacement text of a
    macro.
@@ -180,43 +139,16 @@ copy_comment (pfile, cur, in_define)
      const uchar *cur;
      int in_define;
 {
+  bool unterminated, copy = false;
   unsigned int from_line = pfile->line;
-  const uchar *limit = RLIMIT (pfile->context);
-  uchar *out = pfile->out.cur;
-
-  do
-    {
-      unsigned int c = *cur++;
-      *out++ = c;
-
-      if (c == '/')
-       {
-         /* An immediate slash does not terminate the comment.  */
-         if (out[-2] == '*' && out - 2 > pfile->out.cur)
-           goto done;
-
-         if (*cur == '*' && cur[1] != '/'
-             && CPP_OPTION (pfile, warn_comments))
-           cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0,
-                                "\"/*\" within comment");
-       }
-      else if (is_vspace (c))
-       {
-         cur = handle_newline (pfile, cur - 1);
-         /* Canonicalize newline sequences and skip escaped ones.  */
-         if (out[-2] == '\\')
-           out -= 2;
-         else
-           out[-1] = '\n';
-       }
-    }
-  while (cur < limit);
+  cpp_buffer *buffer = pfile->buffer;
 
-  cpp_error_with_line (pfile, DL_ERROR, from_line, 0, "unterminated comment");
-  *out++ = '*';
-  *out++ = '/';
+  buffer->cur = cur;
+  unterminated = _cpp_skip_block_comment (pfile);
+  if (unterminated)
+    cpp_error_with_line (pfile, DL_ERROR, from_line, 0,
+                        "unterminated comment");
 
- done:
   /* Comments in directives become spaces so that tokens are properly
      separated when the ISO preprocessor re-lexes the line.  The
      exception is #define.  */
@@ -227,7 +159,7 @@ copy_comment (pfile, cur, in_define)
          if (CPP_OPTION (pfile, discard_comments_in_macro_exp))
            pfile->out.cur--;
          else
-           pfile->out.cur = out;
+           copy = true;
        }
       else
        pfile->out.cur[-1] = ' ';
@@ -235,9 +167,21 @@ copy_comment (pfile, cur, in_define)
   else if (CPP_OPTION (pfile, discard_comments))
     pfile->out.cur--;
   else
-    pfile->out.cur = out;
+    copy = true;
 
-  return cur;
+  if (copy)
+    {
+      size_t len = (size_t) (buffer->cur - cur);
+      memcpy (pfile->out.cur, cur, len);
+      pfile->out.cur += len;
+      if (unterminated)
+       {
+         *pfile->out.cur++ = '*';
+         *pfile->out.cur++ = '/';
+       }
+    }
+
+  return buffer->cur;
 }
 
 /* CUR points to any character in the input buffer.  Skips over all
@@ -265,31 +209,18 @@ skip_whitespace (pfile, cur, skip_comments)
       unsigned int c = *cur++;
       *out++ = c;
 
-      if (is_nvspace (c) && c)
+      if (is_nvspace (c))
        continue;
 
-      if (!c && cur - 1 != RLIMIT (pfile->context))
-       continue;
-
-      if (c == '/' && skip_comments)
-       {
-         const uchar *tmp = skip_escaped_newlines (pfile, cur);
-         if (*tmp == '*')
-           {
-             pfile->out.cur = out;
-             cur = copy_comment (pfile, tmp, false /* in_define */);
-             out = pfile->out.cur;
-             continue;
-           }
-       }
-
-      out--;
-      if (c == '\\' && is_vspace (*cur))
+      if (c == '/' && *cur == '*' && skip_comments)
        {
-         cur = skip_escaped_newlines (pfile, cur - 1);
+         pfile->out.cur = out;
+         cur = copy_comment (pfile, cur, false /* in_define */);
+         out = pfile->out.cur;
          continue;
        }
 
+      out--;
       break;
     }
 
@@ -310,12 +241,7 @@ lex_identifier (pfile, cur)
   cpp_hashnode *result;
 
   do
-    {
-      do
-       *out++ = *cur++;
-      while (is_numchar (*cur));
-      cur = skip_escaped_newlines (pfile, cur);
-    }
+    *out++ = *cur++;
   while (is_numchar (*cur));
 
   CUR (pfile->context) = cur;
@@ -340,11 +266,12 @@ _cpp_overlay_buffer (pfile, start, len)
   pfile->overlaid_buffer = buffer;
   buffer->saved_cur = buffer->cur;
   buffer->saved_rlimit = buffer->rlimit;
+  /* Prevent the ISO lexer from scanning a fresh line.  */
+  pfile->saved_line = pfile->line--;
+  buffer->need_line = false;
 
   buffer->cur = start;
   buffer->rlimit = start + len;
-
-  pfile->saved_line = pfile->line;
 }
 
 /* Restores a buffer overlaid by _cpp_overlay_buffer().  */
@@ -356,7 +283,9 @@ _cpp_remove_overlay (pfile)
 
   buffer->cur = buffer->saved_cur;
   buffer->rlimit = buffer->saved_rlimit;
+  buffer->need_line = true;
 
+  pfile->overlaid_buffer = NULL;
   pfile->line = pfile->saved_line;
 }
 
@@ -368,24 +297,10 @@ _cpp_read_logical_line_trad (pfile)
 {
   do
     {
-      if (pfile->buffer->cur == pfile->buffer->rlimit)
-       {
-         bool stop = true;
-
-         /* Don't pop the last buffer.  */
-         if (pfile->buffer->prev)
-           {
-             stop = pfile->buffer->return_at_eof;
-             _cpp_pop_buffer (pfile);
-           }
-
-         if (stop)
-           return false;
-       }
-
-      scan_out_logical_line (pfile, NULL);
+      if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile))
+       return false;
     }
-  while (pfile->state.skipping);
+  while (!scan_out_logical_line (pfile, NULL) || pfile->state.skipping);
 
   return true;
 }
@@ -428,11 +343,12 @@ save_argument (macro, offset)
    If MACRO is non-NULL, then we are scanning the replacement list of
    MACRO, and we call save_replacement_text() every time we meet an
    argument.  */
-static void
+bool
 scan_out_logical_line (pfile, macro)
      cpp_reader *pfile;
      cpp_macro *macro;
 {
+  bool result = true;
   cpp_context *context;
   const uchar *cur;
   uchar *out;
@@ -443,7 +359,6 @@ scan_out_logical_line (pfile, macro)
 
   fmacro.buff = NULL;
 
- start_logical_line:
   quote = 0;
   header_ok = pfile->state.angled_headers;
   CUR (pfile->context) = pfile->buffer->cur;
@@ -458,6 +373,12 @@ scan_out_logical_line (pfile, macro)
 
   for (;;)
     {
+      if (!context->prev
+         && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos)
+       {
+         pfile->buffer->cur = cur;
+         _cpp_process_line_notes (pfile, false);
+       }
       c = *cur++;
       *out++ = c;
 
@@ -469,12 +390,10 @@ scan_out_logical_line (pfile, macro)
        case '\t':
        case '\f':
        case '\v':
-         continue;
-
        case '\0':
-         if (cur - 1 != RLIMIT (context))
-           continue;
+         continue;
 
+       case '\n':
          /* If this is a macro's expansion, pop it.  */
          if (context->prev)
            {
@@ -483,22 +402,21 @@ scan_out_logical_line (pfile, macro)
              goto new_context;
            }
 
-         /* Premature end of file.  Fake a new line.  */
-         cur--;
-         if (!pfile->buffer->from_stage3)
-           cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
+         /* Omit the newline from the output buffer.  */
+         pfile->out.cur = out - 1;
+         pfile->buffer->cur = cur;
+         pfile->buffer->need_line = true;
          pfile->line++;
-         goto done;
 
-       case '\r': case '\n':
-         cur = handle_newline (pfile, cur - 1);
          if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
-             && !pfile->state.in_directive)
+             && !pfile->state.in_directive
+             && _cpp_get_fresh_line (pfile))
            {
              /* Newlines in arguments become a space, but we don't
                 clear any in-progress quote.  */
              if (lex_state == ls_fun_close)
                out[-1] = ' ';
+             cur = pfile->buffer->cur;
              continue;
            }
          goto done;
@@ -521,35 +439,20 @@ scan_out_logical_line (pfile, macro)
          break;
 
        case '\\':
-         if (is_vspace (*cur))
-           {
-             out--;
-             cur = skip_escaped_newlines (pfile, cur - 1);
-             continue;
-           }
-         else
-           {
-             /* Skip escaped quotes here, it's easier than above, but
-                take care to first skip escaped newlines.  */
-             cur = skip_escaped_newlines (pfile, cur);
-             if (*cur == '\\' || *cur == '"' || *cur == '\'')
-               *out++ = *cur++;
-           }
+         /* Skip escaped quotes here, it's easier than above.  */
+         if (*cur == '\\' || *cur == '"' || *cur == '\'')
+           *out++ = *cur++;
          break;
 
        case '/':
          /* Traditional CPP does not recognize comments within
             literals.  */
-         if (!quote)
+         if (!quote && *cur == '*')
            {
-             cur = skip_escaped_newlines (pfile, cur);
-             if (*cur == '*')
-               {
-                 pfile->out.cur = out;
-                 cur = copy_comment (pfile, cur, macro != 0);
-                 out = pfile->out.cur;
-                 continue;
-               }
+             pfile->out.cur = out;
+             cur = copy_comment (pfile, cur, macro != 0);
+             out = pfile->out.cur;
+             continue;
            }
          break;
 
@@ -699,12 +602,14 @@ scan_out_logical_line (pfile, macro)
              cur = skip_whitespace (pfile, cur, true /* skip_comments */);
              out = pfile->out.cur;
 
-             if (is_vspace (*cur))
+             if (*cur == '\n')
                {
                  /* Null directive.  Ignore it and don't invalidate
                     the MI optimization.  */
-                 out = pfile->out.base;
-                 continue;
+                 pfile->buffer->need_line = true;
+                 pfile->line++;
+                 result = false;
+                 goto done;
                }
              else
                {
@@ -724,9 +629,8 @@ scan_out_logical_line (pfile, macro)
                         preprocessor lex the next token.  */
                      pfile->buffer->cur = cur;
                      _cpp_handle_directive (pfile, false /* indented */);
-                     /* #include changes pfile->buffer so we need to
-                        update the limits of the current context.  */
-                     goto start_logical_line;
+                     result = false;
+                     goto done;
                    }
                }
            }
@@ -765,9 +669,6 @@ scan_out_logical_line (pfile, macro)
     }
 
  done:
-  out[-1] = '\0';
-  pfile->buffer->cur = cur;
-  pfile->out.cur = out - 1;
   if (fmacro.buff)
     _cpp_release_buff (pfile, fmacro.buff);
 
@@ -775,6 +676,7 @@ scan_out_logical_line (pfile, macro)
     cpp_error_with_line (pfile, DL_ERROR, fmacro.line, 0,
                         "unterminated argument list invoking macro \"%s\"",
                         NODE_NAME (fmacro.node));
+  return result;
 }
 
 /* Push a context holding the replacement text of the macro NODE on
@@ -787,11 +689,16 @@ push_replacement_text (pfile, node)
 {
   size_t len;
   const uchar *text;
+  uchar *buf;
 
   if (node->flags & NODE_BUILTIN)
     {
       text = _cpp_builtin_macro_text (pfile, node);
       len = ustrlen (text);
+      buf = _cpp_unaligned_alloc (pfile, len + 1);
+      memcpy (buf, text, len);
+      buf[len]='\n';
+      text = buf;
     }
   else
     {
@@ -944,7 +851,7 @@ replace_args_and_push (pfile, fmacro)
          exp += BLOCK_LEN (b->text_len);
        }
 
-      /* Allocate room for the expansion plus NUL.  */
+      /* Allocate room for the expansion plus \n.  */
       buff = _cpp_get_buff (pfile, len + 1);
 
       /* Copy the expansion and replace arguments.  */
@@ -966,8 +873,8 @@ replace_args_and_push (pfile, fmacro)
          exp += BLOCK_LEN (b->text_len);
        }
 
-      /* NUL-terminate.  */
-      *p = '\0';
+      /* \n-terminate.  */
+      *p = '\n';
       _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
 
       /* So we free buffer allocation when macro is left.  */
@@ -1034,10 +941,10 @@ save_replacement_text (pfile, macro, arg_index)
   if (macro->paramc == 0)
     {
       /* Object-like and function-like macros without parameters
-        simply store their NUL-terminated replacement text.  */
+        simply store their \n-terminated replacement text.  */
       exp = _cpp_unaligned_alloc (pfile, len + 1);
       memcpy (exp, pfile->out.base, len);
-      exp[len] = '\0';
+      exp[len] = '\n';
       macro->exp.text = exp;
       macro->count = len;
     }
index 033019eb84934dc4b434e3af983754cf3c5eb05e..f76cbd146a036e6c3518d0f88d75bb53d8628cfe 100644 (file)
@@ -692,7 +692,7 @@ read_scan_file (in_fname, argc, argv)
   if (special_file_handling == stdio_h
       && (fn = lookup_std_proto ("_filbuf", 7)) != NULL)
     {
-      static const unsigned char getchar_call[] = "getchar();";
+      unsigned char getchar_call[] = "getchar();\n";
       int seen_filbuf = 0;
 
       /* Scan the macro expansion of "getchar();".  */
index 99c3b2b12dfb4bd42d54066b661b49b0cd6a2877..fc71e0cf9c389f05c6c72c3e836470ef97d346c8 100644 (file)
@@ -1,3 +1,8 @@
+2003-04-19  Neil Booth  <neil@daikokuya.co.uk>
+
+       * gcc.dg/cpp/_Pragma4.c: Remove stray space.
+       * gcc.dg/cpp/trad/escaped-eof.c: Correct line number.
+
 2003-04-18  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * gcc.c-torture/compile/20030418-1.c: New test.
index a7ac42d4e47c7faf35e27b25c7d9c2e54f622942..5c86b02c710cfbde5acdee177b56a2a28371fe31 100644 (file)
@@ -7,6 +7,6 @@ a b c
 
 /*
    { dg-final { if ![file exists _Pragma4.i] { return }                   } }
-   { dg-final { if { [grep _Pragma4.i "#pragma bar "] != "" } { return }  } }
+   { dg-final { if { [grep _Pragma4.i "#pragma bar"] != "" }  { return }  } }
    { dg-final { fail "_Pragma4.c: #pragma appearing on its own line"      } }
 */
index 37ca95c69182c144458f5d319bf2611ccfceda0b..2c9c185b1d2022511db56b97eb0af80d71577dd9 100644 (file)
@@ -2,5 +2,5 @@
 
 /* { dg-do preprocess } */
 
-/* { dg-warning "backslash-new" "escaped EOF warning" { target *-*-* } 7 } */
+/* { dg-warning "backslash-new" "escaped EOF warning" { target *-*-* } 6 } */
 \