aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.co.uk>2003-04-19 00:22:51 +0000
committerNeil Booth <neil@gcc.gnu.org>2003-04-19 00:22:51 +0000
commit26aea0737b2d0c4ee328d547555ae25ab5de9a0a (patch)
tree6e2502497aefe03b070107d7b41bbe6be454b727
parent606c99912372a1fd5354765992eaef014ab78ce2 (diff)
downloadgcc-26aea0737b2d0c4ee328d547555ae25ab5de9a0a.zip
gcc-26aea0737b2d0c4ee328d547555ae25ab5de9a0a.tar.gz
gcc-26aea0737b2d0c4ee328d547555ae25ab5de9a0a.tar.bz2
cppfiles.c (ENABLE_VALGRIND_CHECKING, [...]): Remove.
* 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
-rw-r--r--gcc/ChangeLog49
-rw-r--r--gcc/cppfiles.c98
-rw-r--r--gcc/cpphash.h52
-rw-r--r--gcc/cppinit.c12
-rw-r--r--gcc/cpplex.c592
-rw-r--r--gcc/cpplib.c51
-rw-r--r--gcc/cppmacro.c24
-rw-r--r--gcc/cpppch.c3
-rw-r--r--gcc/cpptrad.c253
-rw-r--r--gcc/fix-header.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/_Pragma4.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/trad/escaped-eof.c2
13 files changed, 451 insertions, 694 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1b9bb92..978e98a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 1ff34ff..4b8643d 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -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
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index bc0d099..4b5cd49 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -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));
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 376d72e..74679c0 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -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;
+ }
}
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 93e04b8..930e887 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -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);
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 7d2d965..bb983b0 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -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);
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index 94fa858..0898dac 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -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);
diff --git a/gcc/cpppch.c b/gcc/cpppch.c
index 388a753..602711a 100644
--- a/gcc/cpppch.c
+++ b/gcc/cpppch.c
@@ -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);
diff --git a/gcc/cpptrad.c b/gcc/cpptrad.c
index 92c4ee3..f2f94f6 100644
--- a/gcc/cpptrad.c
+++ b/gcc/cpptrad.c
@@ -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;
}
diff --git a/gcc/fix-header.c b/gcc/fix-header.c
index 033019e..f76cbd1 100644
--- a/gcc/fix-header.c
+++ b/gcc/fix-header.c
@@ -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();". */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 99c3b2b..fc71e0c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/cpp/_Pragma4.c b/gcc/testsuite/gcc.dg/cpp/_Pragma4.c
index a7ac42d..5c86b02 100644
--- a/gcc/testsuite/gcc.dg/cpp/_Pragma4.c
+++ b/gcc/testsuite/gcc.dg/cpp/_Pragma4.c
@@ -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" } }
*/
diff --git a/gcc/testsuite/gcc.dg/cpp/trad/escaped-eof.c b/gcc/testsuite/gcc.dg/cpp/trad/escaped-eof.c
index 37ca95c..2c9c185 100644
--- a/gcc/testsuite/gcc.dg/cpp/trad/escaped-eof.c
+++ b/gcc/testsuite/gcc.dg/cpp/trad/escaped-eof.c
@@ -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 } */
\